├── .vs
├── ProjectSettings.json
└── slnx.sqlite
├── LICENSE
├── MyContacts.Droid
├── .DS_Store
├── Assets
│ └── AboutAssets.txt
├── Effects
│ ├── DropShadowEffect.cs
│ └── ListViewSortableEffect.cs
├── MainActivity.cs
├── MyContacts.Droid.csproj
├── MyContacts.Droid.csproj.bak
├── Properties
│ ├── AndroidManifest.xml
│ └── AssemblyInfo.cs
├── Resources
│ ├── AboutResources.txt
│ ├── Resource.Designer.cs
│ ├── drawable-hdpi
│ │ └── icon.png
│ ├── drawable-xhdpi
│ │ └── icon.png
│ ├── drawable-xxhdpi
│ │ └── icon.png
│ ├── drawable
│ │ ├── ic_action_search.png
│ │ ├── icon.png
│ │ └── star.png
│ └── values
│ │ └── styles.xml
└── packages.config
├── MyContacts.UWP
├── App.xaml
├── App.xaml.cs
├── Assets
│ ├── LockScreenLogo.scale-200.png
│ ├── SplashScreen.scale-200.png
│ ├── Square150x150Logo.scale-200.png
│ ├── Square44x44Logo.scale-200.png
│ ├── Square44x44Logo.targetsize-24_altform-unplated.png
│ ├── StoreLogo.png
│ └── Wide310x150Logo.scale-200.png
├── MainPage.xaml
├── MainPage.xaml.cs
├── MyContacts.UWP.csproj
├── Package.appxmanifest
├── Properties
│ ├── AssemblyInfo.cs
│ └── Default.rd.xml
├── project.json
└── star.png
├── MyContacts.iOS
├── AppDelegate.cs
├── Effects
│ └── DropShadowEffect.cs
├── Entitlements.plist
├── Info.plist
├── Main.cs
├── MyContacts.iOS.csproj
├── MyContacts.iOS.csproj.user
├── Properties
│ └── AssemblyInfo.cs
├── Resources
│ ├── Default-568h@2x.png
│ ├── Default-Portrait.png
│ ├── Default-Portrait@2x.png
│ ├── Default.png
│ ├── Default@2x.png
│ ├── Icon-60@2x.png
│ ├── Icon-60@3x.png
│ ├── Icon-76.png
│ ├── Icon-76@2x.png
│ ├── Icon-Small-40.png
│ ├── Icon-Small-40@2x.png
│ ├── Icon-Small-40@3x.png
│ ├── Icon-Small.png
│ ├── Icon-Small@2x.png
│ ├── Icon-Small@3x.png
│ ├── LaunchScreen.storyboard
│ ├── star.png
│ └── star@2x.png
├── iTunesArtwork
├── iTunesArtwork@2x
└── packages.config
├── MyContacts.sln
├── MyContacts
├── AllContacts.xaml
├── AllContacts.xaml.cs
├── AllContactsViewModel.cs
├── App.cs
├── ContactDetails.xaml
├── ContactDetails.xaml.cs
├── Converters
│ ├── BirthdayConverter.cs
│ ├── GenderToIndexConverter.cs
│ └── ImageResourceConverter.cs
├── Data
│ ├── Gender.cs
│ ├── Person.cs
│ └── PlayerFactory.cs
├── Effects
│ └── DropShadowEffect.cs
├── Images
│ ├── Apu.gif
│ ├── Bart.gif
│ ├── ComicBookGuy.gif
│ ├── Homer.gif
│ ├── Krusty.gif
│ ├── Lisa.gif
│ ├── Maggie.gif
│ ├── Marge.gif
│ ├── Milhouse.gif
│ ├── MoeSzyslak.gif
│ ├── MrBurns.gif
│ ├── SideshowBob.gif
│ └── WaylonSmithers.gif
├── MyContacts.csproj
├── MyFacade.SecondPart.cs
├── MyFacade.cs
├── ObservableListCollection.cs
├── Properties
│ └── AssemblyInfo.cs
└── packages.config
└── README.md
/.vs/ProjectSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "CurrentProjectSetting": null
3 | }
--------------------------------------------------------------------------------
/.vs/slnx.sqlite:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canbilgin/DragAndDropSort/96652a7c21730f5b34f6773c7b5294b9b3adf95c/.vs/slnx.sqlite
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Can Bilgin
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/MyContacts.Droid/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canbilgin/DragAndDropSort/96652a7c21730f5b34f6773c7b5294b9b3adf95c/MyContacts.Droid/.DS_Store
--------------------------------------------------------------------------------
/MyContacts.Droid/Assets/AboutAssets.txt:
--------------------------------------------------------------------------------
1 | Any raw assets you want to be deployed with your application can be placed in
2 | this directory (and child directories) and given a Build Action of "AndroidAsset".
3 |
4 | These files will be deployed with you package and will be accessible using Android's
5 | AssetManager, like this:
6 |
7 | public class ReadAsset : Activity
8 | {
9 | protected override void OnCreate (Bundle bundle)
10 | {
11 | base.OnCreate (bundle);
12 |
13 | InputStream input = Assets.Open ("my_asset.txt");
14 | }
15 | }
16 |
17 | Additionally, some Android functions will automatically load asset files:
18 |
19 | Typeface tf = Typeface.CreateFromAsset (Context.Assets, "fonts/samplefont.ttf");
20 |
--------------------------------------------------------------------------------
/MyContacts.Droid/Effects/DropShadowEffect.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using MyContacts.Effects;
4 | using MyContacts.Droid;
5 | using Xamarin.Forms;
6 | using Xamarin.Forms.Platform.Android;
7 |
8 | [assembly: ResolutionGroupName("CubiSoft")]
9 | [assembly: ExportEffect(typeof(DropShadowEffect), "DropShadowEffect")]
10 | namespace MyContacts.Droid
11 | {
12 | public class DropShadowEffect : PlatformEffect
13 | {
14 | protected override void OnAttached()
15 | {
16 | try
17 | {
18 | var control = Control??Container as Android.Views.View;
19 |
20 | var effect = (ViewShadowEffect)Element.Effects.FirstOrDefault(e => e is ViewShadowEffect);
21 |
22 | if (effect != null)
23 | {
24 | float radius = effect.Radius;
25 | Android.Graphics.Color color = effect.Color.ToAndroid();
26 | //control.SetShadowLayer(radius, distanceX, distanceY, color);
27 |
28 | control.Elevation = radius;
29 | control.TranslationZ = (effect.DistanceX + effect.DistanceY) / 2;
30 | }
31 | }
32 | catch (Exception ex)
33 | {
34 | Console.WriteLine("Cannot set property on attached control. Error: {0}", ex.Message);
35 | }
36 | }
37 |
38 | protected override void OnDetached()
39 | {
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/MyContacts.Droid/Effects/ListViewSortableEffect.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 | using Android.Animation;
5 | using Android.Content;
6 | using Android.Database;
7 | using Android.Graphics;
8 | using Android.OS;
9 | using Android.Views;
10 | using Java.Lang;
11 | using MyContacts.Droid.Effects;
12 | using MyContacts.Effects;
13 | using Xamarin.Forms;
14 | using Xamarin.Forms.Platform.Android;
15 | using AViews = Android.Views;
16 | using AWidget = Android.Widget;
17 |
18 | [assembly: ExportEffect(typeof(ListViewSortableEffect), "ListViewSortableEffect")]
19 | namespace MyContacts.Droid.Effects
20 | {
21 | public class ListViewSortableEffect : PlatformEffect
22 | {
23 | private DragListAdapter _dragListAdapter = null;
24 |
25 | protected override void OnAttached()
26 | {
27 | var element = Element as ListView;
28 |
29 | if(Control is AWidget.ListView listView)
30 | {
31 | _dragListAdapter = new DragListAdapter(listView, element);
32 | listView.Adapter = _dragListAdapter;
33 | listView.SetOnDragListener(_dragListAdapter);
34 | listView.OnItemLongClickListener = _dragListAdapter;
35 | }
36 | }
37 |
38 | protected override void OnDetached()
39 | {
40 | if (Control is AWidget.ListView listView)
41 | {
42 | listView.Adapter = _dragListAdapter.WrappedAdapter;
43 |
44 | // TODO: Remove the attached listeners
45 | }
46 | }
47 |
48 | protected override void OnElementPropertyChanged(System.ComponentModel.PropertyChangedEventArgs args)
49 | {
50 | if (args.PropertyName == Sorting.IsSortableProperty.PropertyName)
51 | {
52 | _dragListAdapter.DragDropEnabled = Sorting.GetIsSortable(Element);
53 | }
54 | }
55 | }
56 |
57 | public class DragItem : Java.Lang.Object
58 | {
59 | ///
60 | /// Initializes a new instance of the class.
61 | ///
62 | ///
63 | /// The initial index for the data item.
64 | ///
65 | ///
66 | /// The view element that is being dragged.
67 | ///
68 | ///
69 | /// The data item that is bound to the view.
70 | ///
71 | public DragItem(int index, AViews.View view, object dataItem)
72 | {
73 | OriginalIndex = Index = index;
74 | View = view;
75 | Item = dataItem;
76 | }
77 |
78 | ///
79 | /// Gets or sets the current index for the data item.
80 | ///
81 | public int Index { get; set; }
82 |
83 | ///
84 | /// Gets the original index for the data item
85 | ///
86 | public int OriginalIndex { get; }
87 |
88 | ///
89 | /// Gets the data item that is being dragged
90 | ///
91 | public object Item { get; }
92 |
93 | ///
94 | /// Gets the view that is being dragged
95 | ///
96 | public AViews.View View { get; }
97 | }
98 |
99 | public class DragListAdapter :
100 | AWidget.BaseAdapter,
101 | AWidget.IWrapperListAdapter,
102 | AViews.View.IOnDragListener,
103 | AWidget.AdapterView.IOnItemLongClickListener
104 | {
105 | private AWidget.IListAdapter _listAdapter;
106 |
107 | private AWidget.ListView _listView;
108 |
109 | private ListView _element;
110 |
111 | private List _translatedItems = new List();
112 |
113 | ///
114 | /// Initializes a new instance of the class.
115 | ///
116 | ///
117 | /// The list adapter.
118 | ///
119 | ///
120 | /// The list view.
121 | ///
122 | ///
123 | /// The element.
124 | ///
125 | public DragListAdapter(AWidget.ListView listView, ListView element)
126 | {
127 | _listView = listView;
128 | _listAdapter = ((AWidget.IWrapperListAdapter)_listView.Adapter).WrappedAdapter;
129 | _element = element;
130 | }
131 |
132 | public bool DragDropEnabled { get; set; } = false;
133 |
134 | #region IWrapperListAdapter Members
135 |
136 | public AWidget.IListAdapter WrappedAdapter => _listAdapter;
137 |
138 | public override int Count => WrappedAdapter.Count;
139 |
140 | public override bool HasStableIds => WrappedAdapter.HasStableIds;
141 |
142 | public override bool IsEmpty => WrappedAdapter.IsEmpty;
143 |
144 | public override int ViewTypeCount => WrappedAdapter.ViewTypeCount;
145 |
146 | public override bool AreAllItemsEnabled() => WrappedAdapter.AreAllItemsEnabled();
147 |
148 | public override Java.Lang.Object GetItem(int position)
149 | {
150 | return WrappedAdapter.GetItem(position);
151 | }
152 |
153 | public override long GetItemId(int position)
154 | {
155 | return WrappedAdapter.GetItemId(position);
156 | }
157 |
158 | public override int GetItemViewType(int position)
159 | {
160 | return WrappedAdapter.GetItemViewType(position);
161 | }
162 |
163 | public override Android.Views.View GetView(int position, Android.Views.View convertView, ViewGroup parent)
164 | {
165 | var view = WrappedAdapter.GetView(position, convertView, parent);
166 | view.SetOnDragListener(this);
167 | return view;
168 | }
169 |
170 | public override bool IsEnabled(int position)
171 | {
172 | return WrappedAdapter.IsEnabled(position);
173 | }
174 |
175 | private DataSetObserver _observer;
176 |
177 | public override void RegisterDataSetObserver(DataSetObserver observer)
178 | {
179 | _observer = observer;
180 | base.RegisterDataSetObserver(observer);
181 | WrappedAdapter.RegisterDataSetObserver(observer);
182 | }
183 |
184 | public override void UnregisterDataSetObserver(DataSetObserver observer)
185 | {
186 | base.UnregisterDataSetObserver(observer);
187 | WrappedAdapter.UnregisterDataSetObserver(observer);
188 | }
189 |
190 | #endregion
191 |
192 | public bool OnDrag(AViews.View v, DragEvent e)
193 | {
194 | switch (e.Action)
195 | {
196 | case DragAction.Started:
197 | break;
198 | case DragAction.Entered:
199 | System.Diagnostics.Debug.WriteLine($"DragAction.Entered from {v.GetType()}");
200 |
201 | if(!(v is AWidget.ListView))
202 | {
203 | var dragItem = (DragItem)e.LocalState;
204 |
205 | var targetPosition = InsertOntoView(v, dragItem);
206 |
207 | dragItem.Index = targetPosition;
208 |
209 | // Keep a list of items that has translation so we can reset
210 | // them once the drag'n'drop is finished.
211 | _translatedItems.Add(v);
212 | _listView.Invalidate();
213 | }
214 | break;
215 | case DragAction.Location:
216 | //_currentPosition = (int)e.GetY();
217 | //System.Diagnostics.Debug.WriteLine($"DragAction.Location from {v.GetType()} => {_currentPosition}");
218 | break;
219 | case DragAction.Exited:
220 | System.Diagnostics.Debug.WriteLine($"DragAction.Entered from {v.GetType()}");
221 |
222 | if (!(v is AWidget.ListView))
223 | {
224 | var positionEntered = GetListPositionForView(v);
225 | var item1 = _listAdapter.GetItem(positionEntered);
226 |
227 | System.Diagnostics.Debug.WriteLine($"DragAction.Exited index {positionEntered}");
228 | }
229 | break;
230 | case DragAction.Drop:
231 |
232 |
233 | System.Diagnostics.Debug.WriteLine($"DragAction.Drop from {v.GetType()}");
234 |
235 | //}
236 |
237 | break;
238 | case DragAction.Ended:
239 | if (!(v is AWidget.ListView))
240 | {
241 | return false;
242 | }
243 |
244 | System.Diagnostics.Debug.WriteLine($"DragAction.Ended from {v.GetType()}");
245 |
246 | var mobileItem = (DragItem)e.LocalState;
247 |
248 | mobileItem.View.Visibility = ViewStates.Visible;
249 |
250 | foreach (var view in _translatedItems)
251 | {
252 | view.TranslationY = 0;
253 | }
254 |
255 | _translatedItems.Clear();
256 |
257 | if (_element.ItemsSource is IOrderable orderable)
258 | {
259 | orderable.ChangeOrdinal(mobileItem.OriginalIndex, mobileItem.Index);
260 | }
261 |
262 | break;
263 | }
264 |
265 | return true;
266 | }
267 |
268 | ///
269 | /// Handler for Long Click event from
270 | ///
271 | ///
272 | /// The parent list view .
273 | ///
274 | ///
275 | /// The view that triggered the long click event
276 | ///
277 | ///
278 | /// The position of the view in the list (has to be normalized, includes headers).
279 | ///
280 | ///
281 | /// The id of the item that triggered the event (must be bigger than 0 under normal circumstances).
282 | ///
283 | ///
284 | /// The flag that identifies whether the event is handled.
285 | ///
286 | public bool OnItemLongClick(AWidget.AdapterView parent, AViews.View view, int position, long id)
287 | {
288 | var selectedItem = ((IList)_element.ItemsSource)[(int)id];
289 |
290 | DragItem dragItem = new DragItem(NormalizeListPosition(position), view, selectedItem);
291 |
292 | var data = ClipData.NewPlainText(string.Empty, string.Empty);
293 |
294 | AViews.View.DragShadowBuilder shadowBuilder = new AViews.View.DragShadowBuilder(view);
295 |
296 | view.Visibility = ViewStates.Invisible;
297 |
298 | if (Build.VERSION.SdkInt >= BuildVersionCodes.N)
299 | {
300 | view.StartDragAndDrop(data, shadowBuilder, dragItem, 0);
301 | }
302 | else
303 | {
304 | view.StartDrag(data, shadowBuilder, id, 0);
305 | }
306 |
307 | return true;
308 | }
309 |
310 | private int InsertOntoView(AViews.View view, DragItem item)
311 | {
312 | var positionEntered = GetListPositionForView(view);
313 | var correctedPosition = positionEntered;
314 |
315 | // If the view already has a translation, we need to adjust the position
316 | // If the view has a positive translation, that means that the current position
317 | // is actually one index down then where it started.
318 | // If the view has a negative translation, that means it actually moved
319 | // up previous now we will need to move it down.
320 | if (view.TranslationY > 0)
321 | {
322 | correctedPosition += 1;
323 | }
324 | else if (view.TranslationY < 0)
325 | {
326 | correctedPosition -= 1;
327 | }
328 |
329 | // If the current index of the dragging item is bigger than the target
330 | // That means the dragging item is moving up, and the target view should
331 | // move down, and vice-versa
332 | var translationCoef = item.Index > correctedPosition ? 1 : -1;
333 |
334 | // We translate the item as much as the height of the drag item (up or down)
335 | var translationTarget = view.TranslationY + (translationCoef * item.View.Height);
336 |
337 | ObjectAnimator anim = ObjectAnimator.OfFloat(view, "TranslationY", view.TranslationY, translationTarget);
338 | anim.SetDuration(100);
339 | anim.Start();
340 |
341 | return correctedPosition;
342 | }
343 |
344 | private int GetListPositionForView(AViews.View view)
345 | {
346 | return NormalizeListPosition(_listView.GetPositionForView(view));
347 | }
348 |
349 | private int NormalizeListPosition(int position)
350 | {
351 | return position - _listView.HeaderViewsCount;
352 | }
353 |
354 | }
355 | }
356 |
357 | /*
358 | public class LongClickListener : Java.Lang.Object, AWidget.AdapterView.IOnItemLongClickListener
359 | {
360 | public bool OnItemLongClick(AWidget.AdapterView parent, Android.Views.View view, int position, long id)
361 | {
362 | System.Diagnostics.Debug.WriteLine("EVENT: On Item Long Click Handler");
363 | var data = ClipData.NewPlainText(string.Empty, string.Empty);
364 |
365 | DragShadowBuilder shadowBuilder = new global::Android.Views.View.DragShadowBuilder(view);
366 |
367 | view.Visibility = ViewStates.Invisible;
368 |
369 | long itemId = id;
370 |
371 | if (Build.VERSION.SdkInt >= BuildVersionCodes.N)
372 | {
373 | var itemPosition = position - parent.FirstVisiblePosition;
374 | itemId = parent.GetItemIdAtPosition(itemPosition);
375 | view.StartDragAndDrop(data, shadowBuilder, itemId, 0);
376 | System.Diagnostics.Debug.WriteLine($"Item being dragged with {view.Id} and parameters position {position} and id {itemId}");
377 | }
378 | else
379 | {
380 | view.StartDrag(data, shadowBuilder, itemId, 0);
381 | }
382 |
383 | //view.StartDrag(data, shadowBuilder, tmpObj, 0);
384 |
385 | return true;
386 | }
387 |
388 | public bool OnLongClick(Android.Views.View v)
389 | {
390 | throw new NotImplementedException();
391 | }
392 | }
393 |
394 | public class DragListener : Java.Lang.Object, Android.Views.View.IOnDragListener, Android.Views.View.IOnTouchListener
395 | {
396 | private AWidget.ListView _listView;
397 |
398 | private ListView _element;
399 |
400 | private static int _lastPosition = 0;
401 |
402 | private static float _currentPointerPosition = -1;
403 |
404 | public DragListener(AWidget.ListView listView, ListView element)
405 | {
406 | _listView = listView;
407 | _element = element;
408 |
409 | if (_listView != null)
410 | {
411 | }
412 | }
413 |
414 | ///
415 | /// This Method handles the animation of the cells switching as also switches the underlying data set
416 | ///
417 | void HandleCellSwitch(Android.Views.View switchView, float diff)
418 | {
419 | try
420 | {
421 | //int deltaY = mLastEventY - mDownY; // total distance moved since the last movement
422 | //int deltaYTotal = mHoverCellOriginalBounds.Top + mTotalOffset + deltaY; // total distance moved from original long press position
423 |
424 | //View belowView = GetViewForID(mBelowItemId); // the view currently below the mobile item
425 | //View mobileView = GetViewForID(mMobileItemId); // the current mobile item view (this is NOT what you see moving around, thats just a dummy, this is the "invisible" cell on the list)
426 | //View aboveView = GetViewForID(mAboveItemId); // the view currently above the mobile item
427 |
428 | //// Detect if we have moved the drawable enough to justify a cell swap
429 | //bool isBelow = (belowView != null) && (deltaYTotal > belowView.Top);
430 | //bool isAbove = (aboveView != null) && (deltaYTotal < aboveView.Top);
431 |
432 | //if (isBelow || isAbove)
433 | //{
434 |
435 | //View switchView = isBelow ? belowView : aboveView; // get the view we need to animate
436 |
437 | //var diff = GetViewForID(mMobileItemId).Top - switchView.Top; // the difference between the top of the mobile view and top of the view we are about to switch with
438 |
439 | //// Lets animate the view sliding into its new position. Remember: the listview cell corresponding the mobile item is invisible so it looks like
440 | //// the switch view is just sliding into position
441 | ObjectAnimator anim = ObjectAnimator.OfFloat(switchView, "TranslationY", switchView.TranslationY, switchView.TranslationY + diff);
442 | anim.SetDuration(100);
443 | anim.Start();
444 |
445 |
446 | //// Swap out the mobile item id
447 | //mMobileItemId = GetPositionForView(switchView);
448 |
449 | //// Since the mobile item id has been updated, we also need to make sure and update the above and below item ids
450 | //UpdateNeighborViewsForID(mMobileItemId);
451 |
452 | //// One the animation ends, we want to adjust out visiblity
453 | //anim.AnimationEnd += (sender, e) =>
454 | //{
455 | // // Swap the visbility of the views corresponding to the data items being swapped - since the "switchView" will become the "mobileView"
456 | // // mobileView.Visibility = ViewStates.Visible;
457 | // // switchView.Visibility = ViewStates.Invisible;
458 |
459 | // // Swap the items in the data source and then NotifyDataSetChanged()
460 | // ((IDraggableListAdapter)Adapter).SwapItems(GetPositionForView(mobileView), GetPositionForView(switchView));
461 | //};
462 | //}
463 | }
464 | catch (System.Exception ex)
465 | {
466 | Console.WriteLine("Error Switching Cells in DynamicListView.cs - Message: {0}", ex.Message);
467 | Console.WriteLine("Error Switching Cells in DynamicListView.cs - Stacktrace: {0}", ex.StackTrace);
468 |
469 | }
470 | }
471 |
472 | public bool OnDrag(Android.Views.View v, DragEvent e)
473 | {
474 | switch (e.Action)
475 | {
476 | case Android.Views.DragAction.Started:
477 | break;
478 | case Android.Views.DragAction.Entered:
479 | if (!(v is AWidget.ListView))
480 | {
481 | v.SetBackgroundColor(Android.Graphics.Color.Blue);
482 | var position = (int)_listView?.GetPositionForView(v);
483 |
484 | System.Diagnostics.Debug.WriteLine($"The item is currently on position {position}");
485 | }
486 | break;
487 | case Android.Views.DragAction.Location:
488 | if((v is AWidget.ListView))
489 | {
490 | _currentPointerPosition = e.GetY();
491 | System.Diagnostics.Debug.WriteLine($"The drag.location: {e.GetY()}");
492 | }
493 | return false;
494 | case Android.Views.DragAction.Exited:
495 | if (!(v is AWidget.ListView))
496 | {
497 | v.SetBackgroundColor(Android.Graphics.Color.Transparent);
498 | var position = _listView.GetPositionForView(v);
499 |
500 | var dragListAdapter = (_listView.Adapter as AWidget.IWrapperListAdapter).WrappedAdapter as DragListAdapter;
501 | var id = (int)e.LocalState;
502 |
503 | var mobileView = dragListAdapter.GetViewForId(id);
504 |
505 | var diff = (_currentPointerPosition- v.Top) > 0? 1 : -1;
506 |
507 | System.Diagnostics.Debug.WriteLine($"The item is exiting position {v.Top} - cursor position is {mobileView.Top}");
508 |
509 | HandleCellSwitch(v, (float)(120 * diff));
510 |
511 | _lastPosition = position;
512 |
513 | System.Diagnostics.Debug.WriteLine($"The item is exiting position {position} - and moving id is {id} with diff {diff}");
514 | }
515 | break;
516 | case Android.Views.DragAction.Drop:
517 |
518 | v.SetBackgroundColor(Android.Graphics.Color.Transparent);
519 | var dragListAdapter2 = (_listView.Adapter as AWidget.IWrapperListAdapter).WrappedAdapter as DragListAdapter;
520 | var id2 = (long)e.LocalState;
521 | //var actualId = _listView.GetItemIdAtPosition(id2);
522 | var mobileItem = dragListAdapter2.GetViewForId(id2);
523 | mobileItem.Visibility = ViewStates.Visible;
524 | var position2 = _listView.GetPositionForView(mobileItem);
525 |
526 | if (_element.ItemsSource is IOrderable orderableList)
527 | {
528 | var deleteAt = position2 - 2;
529 | var insertAt = _lastPosition - 2;
530 |
531 | orderableList.ChangeOrdinal(deleteAt, insertAt);
532 |
533 | }
534 | dragListAdapter2.NotifyCollectionChanged();
535 | for (var i = 0; i < _listView.ChildCount; i++)
536 | {
537 | _listView.GetChildAt(i).TranslationY = 0;
538 | }
539 | //_listView.Invalidate();
540 |
541 | break;
542 | case Android.Views.DragAction.Ended:
543 | break;
544 | }
545 |
546 | return true;
547 | }
548 |
549 | public bool OnHover(Android.Views.View v, MotionEvent e)
550 | {
551 | if(v is AWidget.ListView)
552 | {
553 | System.Diagnostics.Debug.WriteLine($"Hover event with Y: {e.GetY()}");
554 | }
555 |
556 | return false;
557 | }
558 |
559 | public bool OnTouch(Android.Views.View v, MotionEvent e)
560 | {
561 | if (e.Action == MotionEventActions.Move)
562 | {
563 | System.Diagnostics.Debug.WriteLine($"Hover event with Y: {e.GetY()}");
564 | }
565 | return false;
566 | }
567 | }
568 |
569 |
570 | */
571 |
572 |
573 |
574 | //private Android.Views.View GetChild(int xCoordinate, int yCoordinate, out int position)
575 | //{
576 | // position = -1;
577 |
578 | // Rect rect = new Rect();
579 | // int[] listViewCoords = new int[2];
580 |
581 | // _listView.GetLocationOnScreen(listViewCoords);
582 |
583 | // int x = xCoordinate - listViewCoords[0];
584 | // int y = yCoordinate - listViewCoords[1];
585 |
586 | // Android.Views.View child;
587 |
588 | // for (int i = 0; i < _listView.ChildCount; i++)
589 | // {
590 | // child = _listView.GetChildAt(i);
591 | // child.GetHitRect(rect);
592 | // if (rect.Contains(x, y))
593 | // {
594 | // position = i;
595 |
596 | // return child;
597 | // }
598 | // }
599 |
600 | // return null;
601 | //}
--------------------------------------------------------------------------------
/MyContacts.Droid/MainActivity.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | using Android.App;
4 | using Android.Content.PM;
5 | using Android.Runtime;
6 | using Android.Views;
7 | using Android.Widget;
8 | using Android.OS;
9 |
10 | namespace MyContacts.Droid
11 | {
12 | [Activity(Label = "Fenerbahce", Theme = "@android:style/Theme.Material.Light", Icon = "@drawable/icon", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
13 | public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsApplicationActivity
14 | {
15 | protected override void OnCreate(Bundle bundle)
16 | {
17 | base.OnCreate(bundle);
18 | global::Xamarin.Forms.Forms.Init(this, bundle);
19 | LoadApplication(new App());
20 |
21 | ActionBar.SetIcon(Android.Resource.Color.Transparent);
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------
/MyContacts.Droid/MyContacts.Droid.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {AE4ADBDC-F8FD-47EC-935C-6EAD95335A40}
8 | {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
9 | Library
10 | Properties
11 | MyContacts.Droid
12 | MyContacts.Droid
13 | 512
14 | true
15 | Resources\Resource.Designer.cs
16 | Off
17 | Properties\AndroidManifest.xml
18 | True
19 | armeabi,armeabi-v7a,x86
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | v8.0
28 | false
29 |
30 |
31 | true
32 | full
33 | false
34 | bin\Debug\
35 | DEBUG;TRACE
36 | prompt
37 | 4
38 | None
39 | x86
40 | false
41 | true
42 | x86
43 |
44 |
45 | pdbonly
46 | true
47 | bin\Release\
48 | TRACE
49 | prompt
50 | 4
51 |
52 |
53 |
54 | ..\packages\Xamarin.Forms.2.3.4.247\lib\MonoAndroid10\FormsViewGroup.dll
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 | ..\packages\Xamarin.Android.Support.Annotations.25.3.1\lib\MonoAndroid70\Xamarin.Android.Support.Annotations.dll
64 |
65 |
66 | ..\packages\Xamarin.Android.Support.Compat.25.3.1\lib\MonoAndroid70\Xamarin.Android.Support.Compat.dll
67 |
68 |
69 | ..\packages\Xamarin.Android.Support.Core.UI.25.3.1\lib\MonoAndroid70\Xamarin.Android.Support.Core.UI.dll
70 |
71 |
72 | ..\packages\Xamarin.Android.Support.Core.Utils.25.3.1\lib\MonoAndroid70\Xamarin.Android.Support.Core.Utils.dll
73 |
74 |
75 | ..\packages\Xamarin.Android.Support.Media.Compat.25.3.1\lib\MonoAndroid70\Xamarin.Android.Support.Media.Compat.dll
76 |
77 |
78 | ..\packages\Xamarin.Android.Support.Fragment.25.3.1\lib\MonoAndroid70\Xamarin.Android.Support.Fragment.dll
79 |
80 |
81 | ..\packages\Xamarin.Android.Support.Transition.25.3.1\lib\MonoAndroid70\Xamarin.Android.Support.Transition.dll
82 |
83 |
84 | ..\packages\Xamarin.Android.Support.v4.25.3.1\lib\MonoAndroid70\Xamarin.Android.Support.v4.dll
85 |
86 |
87 | ..\packages\Xamarin.Android.Support.v7.CardView.25.3.1\lib\MonoAndroid70\Xamarin.Android.Support.v7.CardView.dll
88 |
89 |
90 | ..\packages\Xamarin.Android.Support.v7.Palette.25.3.1\lib\MonoAndroid70\Xamarin.Android.Support.v7.Palette.dll
91 |
92 |
93 | ..\packages\Xamarin.Android.Support.v7.RecyclerView.25.3.1\lib\MonoAndroid70\Xamarin.Android.Support.v7.RecyclerView.dll
94 |
95 |
96 | ..\packages\Xamarin.Android.Support.Vector.Drawable.25.3.1\lib\MonoAndroid70\Xamarin.Android.Support.Vector.Drawable.dll
97 |
98 |
99 | ..\packages\Xamarin.Android.Support.Animated.Vector.Drawable.25.3.1\lib\MonoAndroid70\Xamarin.Android.Support.Animated.Vector.Drawable.dll
100 |
101 |
102 | ..\packages\Xamarin.Android.Support.v7.AppCompat.25.3.1\lib\MonoAndroid70\Xamarin.Android.Support.v7.AppCompat.dll
103 |
104 |
105 | ..\packages\Xamarin.Android.Support.Design.25.3.1\lib\MonoAndroid70\Xamarin.Android.Support.Design.dll
106 |
107 |
108 | ..\packages\Xamarin.Android.Support.v7.MediaRouter.25.3.1\lib\MonoAndroid70\Xamarin.Android.Support.v7.MediaRouter.dll
109 |
110 |
111 | ..\packages\Xamarin.Forms.2.3.4.247\lib\MonoAndroid10\Xamarin.Forms.Core.dll
112 |
113 |
114 | ..\packages\Xamarin.Forms.2.3.4.247\lib\MonoAndroid10\Xamarin.Forms.Platform.dll
115 |
116 |
117 | ..\packages\Xamarin.Forms.2.3.4.247\lib\MonoAndroid10\Xamarin.Forms.Platform.Android.dll
118 |
119 |
120 | ..\packages\Xamarin.Forms.2.3.4.247\lib\MonoAndroid10\Xamarin.Forms.Xaml.dll
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 | MyContacts
149 | {F7E62AA7-D013-43ED-A5DE-16792269C3BE}
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
--------------------------------------------------------------------------------
/MyContacts.Droid/MyContacts.Droid.csproj.bak:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {AE4ADBDC-F8FD-47EC-935C-6EAD95335A40}
8 | {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
9 | Library
10 | Properties
11 | MyContacts.Droid
12 | MyContacts.Droid
13 | 512
14 | true
15 | Resources\Resource.Designer.cs
16 | Off
17 | Properties\AndroidManifest.xml
18 | True
19 | armeabi,armeabi-v7a,x86
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | v8.0
28 | false
29 |
30 |
31 | true
32 | full
33 | false
34 | bin\Debug\
35 | DEBUG;TRACE
36 | prompt
37 | 4
38 | None
39 | armeabi-v7a
40 | true
41 |
42 |
43 | pdbonly
44 | true
45 | bin\Release\
46 | TRACE
47 | prompt
48 | 4
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 | ..\packages\Xamarin.Android.Support.Annotations.25.3.1\lib\MonoAndroid70\Xamarin.Android.Support.Annotations.dll
59 |
60 |
61 | ..\packages\Xamarin.Android.Support.Compat.25.3.1\lib\MonoAndroid70\Xamarin.Android.Support.Compat.dll
62 |
63 |
64 | ..\packages\Xamarin.Android.Support.Core.UI.25.3.1\lib\MonoAndroid70\Xamarin.Android.Support.Core.UI.dll
65 |
66 |
67 | ..\packages\Xamarin.Android.Support.Core.Utils.25.3.1\lib\MonoAndroid70\Xamarin.Android.Support.Core.Utils.dll
68 |
69 |
70 | ..\packages\Xamarin.Android.Support.Media.Compat.25.3.1\lib\MonoAndroid70\Xamarin.Android.Support.Media.Compat.dll
71 |
72 |
73 | ..\packages\Xamarin.Android.Support.Fragment.25.3.1\lib\MonoAndroid70\Xamarin.Android.Support.Fragment.dll
74 |
75 |
76 | ..\packages\Xamarin.Android.Support.Transition.25.3.1\lib\MonoAndroid70\Xamarin.Android.Support.Transition.dll
77 |
78 |
79 | ..\packages\Xamarin.Android.Support.v4.25.3.1\lib\MonoAndroid70\Xamarin.Android.Support.v4.dll
80 |
81 |
82 | ..\packages\Xamarin.Android.Support.v7.CardView.25.3.1\lib\MonoAndroid70\Xamarin.Android.Support.v7.CardView.dll
83 |
84 |
85 | ..\packages\Xamarin.Android.Support.v7.Palette.25.3.1\lib\MonoAndroid70\Xamarin.Android.Support.v7.Palette.dll
86 |
87 |
88 | ..\packages\Xamarin.Android.Support.v7.RecyclerView.25.3.1\lib\MonoAndroid70\Xamarin.Android.Support.v7.RecyclerView.dll
89 |
90 |
91 | ..\packages\Xamarin.Android.Support.Vector.Drawable.25.3.1\lib\MonoAndroid70\Xamarin.Android.Support.Vector.Drawable.dll
92 |
93 |
94 | ..\packages\Xamarin.Android.Support.Animated.Vector.Drawable.25.3.1\lib\MonoAndroid70\Xamarin.Android.Support.Animated.Vector.Drawable.dll
95 |
96 |
97 | ..\packages\Xamarin.Android.Support.v7.AppCompat.25.3.1\lib\MonoAndroid70\Xamarin.Android.Support.v7.AppCompat.dll
98 |
99 |
100 | ..\packages\Xamarin.Android.Support.Design.25.3.1\lib\MonoAndroid70\Xamarin.Android.Support.Design.dll
101 |
102 |
103 | ..\packages\Xamarin.Android.Support.v7.MediaRouter.25.3.1\lib\MonoAndroid70\Xamarin.Android.Support.v7.MediaRouter.dll
104 |
105 |
106 | ..\packages\Xamarin.Forms.2.3.4.247\lib\MonoAndroid10\FormsViewGroup.dll
107 |
108 |
109 | ..\packages\Xamarin.Forms.2.3.4.247\lib\MonoAndroid10\Xamarin.Forms.Core.dll
110 |
111 |
112 | ..\packages\Xamarin.Forms.2.3.4.247\lib\MonoAndroid10\Xamarin.Forms.Platform.Android.dll
113 |
114 |
115 | ..\packages\Xamarin.Forms.2.3.4.247\lib\MonoAndroid10\Xamarin.Forms.Platform.dll
116 |
117 |
118 | ..\packages\Xamarin.Forms.2.3.4.247\lib\MonoAndroid10\Xamarin.Forms.Xaml.dll
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 | MyContacts
147 | {F7E62AA7-D013-43ED-A5DE-16792269C3BE}
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
--------------------------------------------------------------------------------
/MyContacts.Droid/Properties/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/MyContacts.Droid/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 | using Android.App;
5 |
6 | // General Information about an assembly is controlled through the following
7 | // set of attributes. Change these attribute values to modify the information
8 | // associated with an assembly.
9 | [assembly: AssemblyTitle("MyContacts.Droid")]
10 | [assembly: AssemblyDescription("")]
11 | [assembly: AssemblyConfiguration("")]
12 | [assembly: AssemblyCompany("")]
13 | [assembly: AssemblyProduct("MyContacts.Droid")]
14 | [assembly: AssemblyCopyright("Copyright © 2014")]
15 | [assembly: AssemblyTrademark("")]
16 | [assembly: AssemblyCulture("")]
17 | [assembly: ComVisible(false)]
18 |
19 | // Version information for an assembly consists of the following four values:
20 | //
21 | // Major Version
22 | // Minor Version
23 | // Build Number
24 | // Revision
25 | //
26 | // You can specify all the values or you can default the Build and Revision Numbers
27 | // by using the '*' as shown below:
28 | // [assembly: AssemblyVersion("1.0.*")]
29 | [assembly: AssemblyVersion("1.0.0.0")]
30 | [assembly: AssemblyFileVersion("1.0.0.0")]
31 |
32 | // Add some common permissions, these can be removed if not needed
33 | [assembly: UsesPermission(Android.Manifest.Permission.Internet)]
34 | [assembly: UsesPermission(Android.Manifest.Permission.WriteExternalStorage)]
35 |
--------------------------------------------------------------------------------
/MyContacts.Droid/Resources/AboutResources.txt:
--------------------------------------------------------------------------------
1 | Images, layout descriptions, binary blobs and string dictionaries can be included
2 | in your application as resource files. Various Android APIs are designed to
3 | operate on the resource IDs instead of dealing with images, strings or binary blobs
4 | directly.
5 |
6 | For example, a sample Android app that contains a user interface layout (main.xml),
7 | an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png)
8 | would keep its resources in the "Resources" directory of the application:
9 |
10 | Resources/
11 | drawable-hdpi/
12 | icon.png
13 |
14 | drawable-ldpi/
15 | icon.png
16 |
17 | drawable-mdpi/
18 | icon.png
19 |
20 | layout/
21 | main.xml
22 |
23 | values/
24 | strings.xml
25 |
26 | In order to get the build system to recognize Android resources, set the build action to
27 | "AndroidResource". The native Android APIs do not operate directly with filenames, but
28 | instead operate on resource IDs. When you compile an Android application that uses resources,
29 | the build system will package the resources for distribution and generate a class called
30 | "Resource" that contains the tokens for each one of the resources included. For example,
31 | for the above Resources layout, this is what the Resource class would expose:
32 |
33 | public class Resource {
34 | public class drawable {
35 | public const int icon = 0x123;
36 | }
37 |
38 | public class layout {
39 | public const int main = 0x456;
40 | }
41 |
42 | public class strings {
43 | public const int first_string = 0xabc;
44 | public const int second_string = 0xbcd;
45 | }
46 | }
47 |
48 | You would then use R.drawable.icon to reference the drawable/icon.png file, or Resource.layout.main
49 | to reference the layout/main.xml file, or Resource.strings.first_string to reference the first
50 | string in the dictionary file values/strings.xml.
51 |
--------------------------------------------------------------------------------
/MyContacts.Droid/Resources/drawable-hdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canbilgin/DragAndDropSort/96652a7c21730f5b34f6773c7b5294b9b3adf95c/MyContacts.Droid/Resources/drawable-hdpi/icon.png
--------------------------------------------------------------------------------
/MyContacts.Droid/Resources/drawable-xhdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canbilgin/DragAndDropSort/96652a7c21730f5b34f6773c7b5294b9b3adf95c/MyContacts.Droid/Resources/drawable-xhdpi/icon.png
--------------------------------------------------------------------------------
/MyContacts.Droid/Resources/drawable-xxhdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canbilgin/DragAndDropSort/96652a7c21730f5b34f6773c7b5294b9b3adf95c/MyContacts.Droid/Resources/drawable-xxhdpi/icon.png
--------------------------------------------------------------------------------
/MyContacts.Droid/Resources/drawable/ic_action_search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canbilgin/DragAndDropSort/96652a7c21730f5b34f6773c7b5294b9b3adf95c/MyContacts.Droid/Resources/drawable/ic_action_search.png
--------------------------------------------------------------------------------
/MyContacts.Droid/Resources/drawable/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canbilgin/DragAndDropSort/96652a7c21730f5b34f6773c7b5294b9b3adf95c/MyContacts.Droid/Resources/drawable/icon.png
--------------------------------------------------------------------------------
/MyContacts.Droid/Resources/drawable/star.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canbilgin/DragAndDropSort/96652a7c21730f5b34f6773c7b5294b9b3adf95c/MyContacts.Droid/Resources/drawable/star.png
--------------------------------------------------------------------------------
/MyContacts.Droid/Resources/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
--------------------------------------------------------------------------------
/MyContacts.Droid/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/MyContacts.UWP/App.xaml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/MyContacts.UWP/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Runtime.InteropServices.WindowsRuntime;
6 | using Windows.ApplicationModel;
7 | using Windows.ApplicationModel.Activation;
8 | using Windows.Foundation;
9 | using Windows.Foundation.Collections;
10 | using Windows.UI.Xaml;
11 | using Windows.UI.Xaml.Controls;
12 | using Windows.UI.Xaml.Controls.Primitives;
13 | using Windows.UI.Xaml.Data;
14 | using Windows.UI.Xaml.Input;
15 | using Windows.UI.Xaml.Media;
16 | using Windows.UI.Xaml.Navigation;
17 |
18 | namespace MyContacts.UWP
19 | {
20 | ///
21 | /// Provides application-specific behavior to supplement the default Application class.
22 | ///
23 | sealed partial class App : Application
24 | {
25 | ///
26 | /// Initializes the singleton application object. This is the first line of authored code
27 | /// executed, and as such is the logical equivalent of main() or WinMain().
28 | ///
29 | public App()
30 | {
31 | this.InitializeComponent();
32 | this.Suspending += OnSuspending;
33 | }
34 |
35 | ///
36 | /// Invoked when the application is launched normally by the end user. Other entry points
37 | /// will be used such as when the application is launched to open a specific file.
38 | ///
39 | /// Details about the launch request and process.
40 | protected override void OnLaunched(LaunchActivatedEventArgs e)
41 | {
42 |
43 | #if DEBUG
44 | if (System.Diagnostics.Debugger.IsAttached)
45 | {
46 | this.DebugSettings.EnableFrameRateCounter = true;
47 | }
48 | #endif
49 |
50 | Frame rootFrame = Window.Current.Content as Frame;
51 |
52 | // Do not repeat app initialization when the Window already has content,
53 | // just ensure that the window is active
54 | if (rootFrame == null)
55 | {
56 | // Create a Frame to act as the navigation context and navigate to the first page
57 | rootFrame = new Frame();
58 |
59 | rootFrame.NavigationFailed += OnNavigationFailed;
60 |
61 | Xamarin.Forms.Forms.Init(e);
62 |
63 | if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
64 | {
65 | //TODO: Load state from previously suspended application
66 | }
67 |
68 | // Place the frame in the current Window
69 | Window.Current.Content = rootFrame;
70 | }
71 |
72 | if (rootFrame.Content == null)
73 | {
74 | // When the navigation stack isn't restored navigate to the first page,
75 | // configuring the new page by passing required information as a navigation
76 | // parameter
77 | rootFrame.Navigate(typeof(MainPage), e.Arguments);
78 | }
79 | // Ensure the current window is active
80 | Window.Current.Activate();
81 | }
82 |
83 | ///
84 | /// Invoked when Navigation to a certain page fails
85 | ///
86 | /// The Frame which failed navigation
87 | /// Details about the navigation failure
88 | void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
89 | {
90 | throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
91 | }
92 |
93 | ///
94 | /// Invoked when application execution is being suspended. Application state is saved
95 | /// without knowing whether the application will be terminated or resumed with the contents
96 | /// of memory still intact.
97 | ///
98 | /// The source of the suspend request.
99 | /// Details about the suspend request.
100 | private void OnSuspending(object sender, SuspendingEventArgs e)
101 | {
102 | var deferral = e.SuspendingOperation.GetDeferral();
103 | //TODO: Save application state and stop any background activity
104 | deferral.Complete();
105 | }
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/MyContacts.UWP/Assets/LockScreenLogo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canbilgin/DragAndDropSort/96652a7c21730f5b34f6773c7b5294b9b3adf95c/MyContacts.UWP/Assets/LockScreenLogo.scale-200.png
--------------------------------------------------------------------------------
/MyContacts.UWP/Assets/SplashScreen.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canbilgin/DragAndDropSort/96652a7c21730f5b34f6773c7b5294b9b3adf95c/MyContacts.UWP/Assets/SplashScreen.scale-200.png
--------------------------------------------------------------------------------
/MyContacts.UWP/Assets/Square150x150Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canbilgin/DragAndDropSort/96652a7c21730f5b34f6773c7b5294b9b3adf95c/MyContacts.UWP/Assets/Square150x150Logo.scale-200.png
--------------------------------------------------------------------------------
/MyContacts.UWP/Assets/Square44x44Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canbilgin/DragAndDropSort/96652a7c21730f5b34f6773c7b5294b9b3adf95c/MyContacts.UWP/Assets/Square44x44Logo.scale-200.png
--------------------------------------------------------------------------------
/MyContacts.UWP/Assets/Square44x44Logo.targetsize-24_altform-unplated.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canbilgin/DragAndDropSort/96652a7c21730f5b34f6773c7b5294b9b3adf95c/MyContacts.UWP/Assets/Square44x44Logo.targetsize-24_altform-unplated.png
--------------------------------------------------------------------------------
/MyContacts.UWP/Assets/StoreLogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canbilgin/DragAndDropSort/96652a7c21730f5b34f6773c7b5294b9b3adf95c/MyContacts.UWP/Assets/StoreLogo.png
--------------------------------------------------------------------------------
/MyContacts.UWP/Assets/Wide310x150Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canbilgin/DragAndDropSort/96652a7c21730f5b34f6773c7b5294b9b3adf95c/MyContacts.UWP/Assets/Wide310x150Logo.scale-200.png
--------------------------------------------------------------------------------
/MyContacts.UWP/MainPage.xaml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/MyContacts.UWP/MainPage.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Runtime.InteropServices.WindowsRuntime;
6 | using Windows.Foundation;
7 | using Windows.Foundation.Collections;
8 | using Windows.UI.Xaml;
9 | using Windows.UI.Xaml.Controls;
10 | using Windows.UI.Xaml.Controls.Primitives;
11 | using Windows.UI.Xaml.Data;
12 | using Windows.UI.Xaml.Input;
13 | using Windows.UI.Xaml.Media;
14 | using Windows.UI.Xaml.Navigation;
15 |
16 | // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
17 |
18 | namespace MyContacts.UWP
19 | {
20 | ///
21 | /// An empty page that can be used on its own or navigated to within a Frame.
22 | ///
23 | public sealed partial class MainPage
24 | {
25 | public MainPage()
26 | {
27 | this.InitializeComponent();
28 |
29 | LoadApplication(new MyContacts.App());
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/MyContacts.UWP/MyContacts.UWP.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | x86
7 | {5DD83C16-1132-4ACD-B9C4-93D9D33A4E0C}
8 | AppContainerExe
9 | Properties
10 | MyContacts.UWP
11 | MyContacts.UWP
12 | en-US
13 | UAP
14 | 10.0.14393.0
15 | 10.0.10240.0
16 | 14
17 | true
18 | 512
19 | {A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
20 |
21 |
22 |
23 |
24 | true
25 | bin\ARM\Debug\
26 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
27 | ;2008
28 | full
29 | ARM
30 | false
31 | prompt
32 | true
33 |
34 |
35 | bin\ARM\Release\
36 | TRACE;NETFX_CORE;WINDOWS_UWP
37 | true
38 | ;2008
39 | pdbonly
40 | ARM
41 | false
42 | prompt
43 | true
44 | true
45 |
46 |
47 | true
48 | bin\x64\Debug\
49 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
50 | ;2008
51 | full
52 | x64
53 | false
54 | prompt
55 | true
56 |
57 |
58 | bin\x64\Release\
59 | TRACE;NETFX_CORE;WINDOWS_UWP
60 | true
61 | ;2008
62 | pdbonly
63 | x64
64 | false
65 | prompt
66 | true
67 | true
68 |
69 |
70 | true
71 | bin\x86\Debug\
72 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
73 | ;2008
74 | full
75 | x86
76 | false
77 | prompt
78 | true
79 |
80 |
81 | bin\x86\Release\
82 | TRACE;NETFX_CORE;WINDOWS_UWP
83 | true
84 | ;2008
85 | pdbonly
86 | x86
87 | false
88 | prompt
89 | true
90 | true
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 | App.xaml
99 |
100 |
101 | MainPage.xaml
102 |
103 |
104 |
105 |
106 |
107 | Designer
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 | MSBuild:Compile
124 | Designer
125 |
126 |
127 | MSBuild:Compile
128 | Designer
129 |
130 |
131 |
132 |
133 | {F7E62AA7-D013-43ED-A5DE-16792269C3BE}
134 | MyContacts
135 |
136 |
137 |
138 | 14.0
139 |
140 |
141 |
148 |
--------------------------------------------------------------------------------
/MyContacts.UWP/Package.appxmanifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
13 |
14 |
15 |
16 |
17 | MyContacts.UWP
18 | Xamarin
19 | Assets\StoreLogo.png
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
34 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/MyContacts.UWP/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("MyContacts.UWP")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("MyContacts.UWP")]
13 | [assembly: AssemblyCopyright("Copyright © 2015")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Version information for an assembly consists of the following four values:
18 | //
19 | // Major Version
20 | // Minor Version
21 | // Build Number
22 | // Revision
23 | //
24 | // You can specify all the values or you can default the Build and Revision Numbers
25 | // by using the '*' as shown below:
26 | // [assembly: AssemblyVersion("1.0.*")]
27 | [assembly: AssemblyVersion("1.0.0.0")]
28 | [assembly: AssemblyFileVersion("1.0.0.0")]
29 | [assembly: ComVisible(false)]
--------------------------------------------------------------------------------
/MyContacts.UWP/Properties/Default.rd.xml:
--------------------------------------------------------------------------------
1 |
17 |
18 |
19 |
20 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/MyContacts.UWP/project.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": {
3 | "Microsoft.NETCore.UniversalWindowsPlatform": " 5.2.2",
4 | "Xamarin.Forms": "2.3.3.180"
5 | },
6 | "frameworks": {
7 | "uap10.0": {}
8 | },
9 | "runtimes": {
10 | "win10-arm": {},
11 | "win10-arm-aot": {},
12 | "win10-x86": {},
13 | "win10-x86-aot": {},
14 | "win10-x64": {},
15 | "win10-x64-aot": {}
16 | }
17 | }
--------------------------------------------------------------------------------
/MyContacts.UWP/star.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canbilgin/DragAndDropSort/96652a7c21730f5b34f6773c7b5294b9b3adf95c/MyContacts.UWP/star.png
--------------------------------------------------------------------------------
/MyContacts.iOS/AppDelegate.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 |
5 | using Foundation;
6 | using UIKit;
7 |
8 | namespace MyContacts.iOS
9 | {
10 | // The UIApplicationDelegate for the application. This class is responsible for launching the
11 | // User Interface of the application, as well as listening (and optionally responding) to
12 | // application events from iOS.
13 | [Register("AppDelegate")]
14 | public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
15 | {
16 | //
17 | // This method is invoked when the application has loaded and is ready to run. In this
18 | // method you should instantiate the window, load the UI into it and then make the window
19 | // visible.
20 | //
21 | // You have 17 seconds to return from this method, or iOS will terminate your application.
22 | //
23 | public override bool FinishedLaunching(UIApplication app, NSDictionary options)
24 | {
25 | global::Xamarin.Forms.Forms.Init();
26 | LoadApplication(new App());
27 |
28 | return base.FinishedLaunching(app, options);
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/MyContacts.iOS/Effects/DropShadowEffect.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using CoreGraphics;
4 | using Foundation;
5 | using MyContacts.Effects;
6 | using MyContacts.iOS;
7 | using UIKit;
8 | using Xamarin.Forms;
9 | using Xamarin.Forms.Platform.iOS;
10 |
11 | [assembly: ResolutionGroupName("CubiSoft")]
12 | [assembly: ExportEffect(typeof(DropShadowEffect), "DropShadowEffect")]
13 | [assembly: ExportEffect(typeof(ListViewSortableEffect), "ListViewSortableEffect")]
14 | namespace MyContacts.iOS
15 | {
16 | public class ListViewSortableEffect : PlatformEffect
17 | {
18 | internal UITableView TableView
19 | {
20 | get
21 | {
22 | return Control as UITableView;
23 | }
24 | }
25 |
26 | protected override void OnAttached()
27 | {
28 | if (TableView == null)
29 | {
30 | return;
31 | }
32 | var isSortable = Sorting.GetIsSortable(Element);
33 |
34 | TableView.Source = new ListSortableTableSource(TableView.Source, Element as ListView);
35 | TableView.SetEditing(isSortable, true);
36 | }
37 |
38 | protected override void OnDetached()
39 | {
40 | TableView.Source = (TableView.Source as ListSortableTableSource).OriginalSource;
41 | TableView.SetEditing(false, true);
42 | }
43 |
44 | protected override void OnElementPropertyChanged(System.ComponentModel.PropertyChangedEventArgs args)
45 | {
46 | if (args.PropertyName == Sorting.IsSortableProperty.PropertyName)
47 | {
48 | TableView.SetEditing(Sorting.GetIsSortable(Element), true);
49 | }
50 | }
51 | }
52 |
53 | public class ListSortableTableSource : UITableViewSource
54 | {
55 | private UITableViewSource _originalSource;
56 |
57 | private ListView _formsElement;
58 |
59 | public ListSortableTableSource(UITableViewSource source, ListView element)
60 | {
61 | _originalSource = source;
62 | _formsElement = element;
63 | }
64 |
65 | public UITableViewSource OriginalSource
66 | {
67 | get
68 | {
69 | return _originalSource;
70 | }
71 | }
72 |
73 | public override UITableViewCellEditingStyle EditingStyleForRow(UITableView tableView, NSIndexPath indexPath)
74 | {
75 | // We do not want the "-" icon near each row (or the "+" icon)
76 | return UITableViewCellEditingStyle.None;
77 | }
78 |
79 | public override bool CanEditRow(UITableView tableView, NSIndexPath indexPath)
80 | {
81 | // We still want the row to be editable
82 | return true;
83 | }
84 |
85 | public override bool CanMoveRow(UITableView tableView, NSIndexPath indexPath)
86 | {
87 | // We do want each row to be movable
88 | return true;
89 | }
90 |
91 | public override bool ShouldIndentWhileEditing(UITableView tableView, NSIndexPath indexPath)
92 | {
93 | // We do not want the "weird" indent for the rows when they are in editable mode.
94 | return false;
95 | }
96 |
97 | public override void MoveRow(UITableView tableView, NSIndexPath sourceIndexPath, NSIndexPath destinationIndexPath)
98 | {
99 | if (_formsElement.ItemsSource is IOrderable orderableList)
100 | {
101 | var deleteAt = sourceIndexPath.Row;
102 | var insertAt = destinationIndexPath.Row;
103 |
104 | orderableList.ChangeOrdinal(deleteAt, insertAt);
105 | }
106 | }
107 |
108 |
109 |
110 | //public override void CommitEditingStyle(UITableView tableView, UITableViewCellEditingStyle editingStyle, Foundation.NSIndexPath indexPath)
111 | //{
112 | // switch (editingStyle)
113 | // {
114 | // case UITableViewCellEditingStyle.Delete:
115 | // break;
116 | // case UITableViewCellEditingStyle.None:
117 | // break;
118 | // }
119 | //}
120 |
121 | //public override NSIndexPath CustomizeMoveTarget(UITableView tableView, NSIndexPath sourceIndexPath, NSIndexPath proposedIndexPath)
122 | //{
123 | // var numRows = tableView.NumberOfRowsInSection(0);
124 | // if (proposedIndexPath.Row >= numRows)
125 | // return NSIndexPath.FromRowSection(numRows, 0);
126 | // else
127 | // return proposedIndexPath;
128 | //}
129 |
130 | //public override void DraggingEnded(UIScrollView scrollView, bool willDecelerate)
131 | //{
132 | // _originalSource.DraggingEnded(scrollView, willDecelerate);
133 | //}
134 |
135 | //public override void DraggingStarted(UIScrollView scrollView)
136 | //{
137 | // _originalSource.DraggingStarted(scrollView);
138 | //}
139 |
140 | public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
141 | {
142 | return OriginalSource.GetCell(tableView, indexPath);
143 | }
144 |
145 | public override nfloat GetHeightForHeader(UITableView tableView, nint section)
146 | {
147 | return OriginalSource.GetHeightForHeader(tableView, section);
148 | }
149 |
150 | public override nfloat GetHeightForRow(UITableView tableView, NSIndexPath indexPath)
151 | {
152 | return OriginalSource.GetHeightForRow(tableView, indexPath);
153 | }
154 |
155 | public override UIView GetViewForHeader(UITableView tableView, nint section)
156 | {
157 | return OriginalSource.GetViewForHeader(tableView, section);
158 | }
159 |
160 | public override void HeaderViewDisplayingEnded(UITableView tableView, UIView headerView, nint section)
161 | {
162 | OriginalSource.HeaderViewDisplayingEnded(tableView, headerView, section);
163 | }
164 |
165 | public override nint NumberOfSections(UITableView tableView)
166 | {
167 | return OriginalSource.NumberOfSections(tableView);
168 | }
169 |
170 | public override void RowDeselected(UITableView tableView, NSIndexPath indexPath)
171 | {
172 | OriginalSource.RowDeselected(tableView, indexPath);
173 | }
174 |
175 | public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
176 | {
177 | OriginalSource.RowSelected(tableView, indexPath);
178 | }
179 |
180 | public override nint RowsInSection(UITableView tableview, nint section)
181 | {
182 | return OriginalSource.RowsInSection(tableview, section);
183 | }
184 |
185 | public override void Scrolled(UIScrollView scrollView)
186 | {
187 | OriginalSource.Scrolled(scrollView);
188 | }
189 |
190 | public override string[] SectionIndexTitles(UITableView tableView)
191 | {
192 | return OriginalSource.SectionIndexTitles(tableView);
193 | }
194 | }
195 |
196 | public class DropShadowEffect : PlatformEffect
197 | {
198 | protected override void OnAttached()
199 | {
200 | try
201 | {
202 | var effect = (ViewShadowEffect)Element.Effects.FirstOrDefault(e => e is ViewShadowEffect);
203 |
204 | if (effect != null)
205 | {
206 | Container.Layer.CornerRadius = effect.Radius;
207 | Container.Layer.ShadowColor = effect.Color.ToCGColor();
208 | Container.Layer.ShadowOffset = new CGSize(effect.DistanceX, effect.DistanceY);
209 | Container.Layer.ShadowOpacity = 0.5f;
210 |
211 | var color = GetColor();
212 | Container.Layer.BackgroundColor = new CGColor((nfloat)color.R, (nfloat)color.G, (nfloat)color.B, (nfloat)0.2);
213 | }
214 | }
215 | catch (Exception ex)
216 | {
217 | Console.WriteLine("Cannot set property on attached control. Error: {0}", ex.Message);
218 | }
219 | }
220 |
221 | protected override void OnDetached()
222 | {
223 | }
224 |
225 | private Color GetColor()
226 | {
227 | var currentSpan = (int)DateTime.Now.Second / 10;
228 |
229 | switch(currentSpan)
230 | {
231 | case 0:
232 | return Color.Blue;
233 | case 1:
234 | return Color.Red;
235 | case 2:
236 | return Color.Brown;
237 | case 3:
238 | return Color.Aqua;
239 | case 4:
240 | return Color.Green;
241 | default:
242 | case 5:
243 | return Color.Yellow;
244 |
245 | }
246 | }
247 | }
248 | }
249 |
--------------------------------------------------------------------------------
/MyContacts.iOS/Entitlements.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/MyContacts.iOS/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | UIDeviceFamily
6 |
7 | 1
8 | 2
9 |
10 | UISupportedInterfaceOrientations
11 |
12 | UIInterfaceOrientationPortrait
13 | UIInterfaceOrientationLandscapeLeft
14 | UIInterfaceOrientationLandscapeRight
15 |
16 | UISupportedInterfaceOrientations~ipad
17 |
18 | UIInterfaceOrientationPortrait
19 | UIInterfaceOrientationPortraitUpsideDown
20 | UIInterfaceOrientationLandscapeLeft
21 | UIInterfaceOrientationLandscapeRight
22 |
23 | MinimumOSVersion
24 | 11.2
25 | CFBundleDisplayName
26 | MyContacts
27 | CFBundleIdentifier
28 | com.yourcompany.MyContacts
29 | CFBundleVersion
30 | 1.0
31 | CFBundleIconFiles
32 |
33 | Icon-60@2x
34 | Icon-60@3x
35 | Icon-76
36 | Icon-76@2x
37 | Default
38 | Default@2x
39 | Default-568h@2x
40 | Default-Portrait
41 | Default-Portrait@2x
42 | Icon-Small-40
43 | Icon-Small-40@2x
44 | Icon-Small-40@3x
45 | Icon-Small
46 | Icon-Small@2x
47 | Icon-Small@3x
48 |
49 | UILaunchStoryboardName
50 | LaunchScreen
51 | CFBundleName
52 | MyContacts
53 |
54 |
55 |
--------------------------------------------------------------------------------
/MyContacts.iOS/Main.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 |
5 | using Foundation;
6 | using UIKit;
7 |
8 | namespace MyContacts.iOS
9 | {
10 | public class Application
11 | {
12 | // This is the main entry point of the application.
13 | static void Main(string[] args)
14 | {
15 | // if you want to use a different Application Delegate class from "AppDelegate"
16 | // you can specify it here.
17 | UIApplication.Main(args, null, "AppDelegate");
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/MyContacts.iOS/MyContacts.iOS.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | iPhoneSimulator
6 | {035E6526-E284-4E7C-8AC8-9A309BD1688A}
7 | {FEACFBD2-3405-455C-9665-78FE426C6842};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
8 | Exe
9 | MyContacts.iOS
10 | Resources
11 | MyContactsiOS
12 |
13 |
14 |
15 | true
16 | full
17 | false
18 | bin\iPhoneSimulator\Debug
19 | DEBUG;ENABLE_TEST_CLOUD;
20 | prompt
21 | 4
22 | false
23 | x86_64
24 | None
25 | true
26 | false
27 | iPhone Developer
28 |
29 |
30 | full
31 | true
32 | bin\iPhoneSimulator\Release
33 | prompt
34 | 4
35 | i386, x86_64
36 | false
37 | None
38 |
39 |
40 | true
41 | full
42 | false
43 | bin\iPhone\Debug
44 | DEBUG;ENABLE_TEST_CLOUD;
45 | prompt
46 | 4
47 | false
48 | ARMv7, ARM64
49 | Entitlements.plist
50 | true
51 | iPhone Developer
52 | true
53 | 11.2
54 |
55 |
56 | full
57 | true
58 | bin\iPhone\Release
59 | prompt
60 | 4
61 | Entitlements.plist
62 | ARMv7, ARM64
63 | false
64 | iPhone Developer
65 |
66 |
67 | none
68 | True
69 | bin\iPhone\Ad-Hoc
70 | prompt
71 | 4
72 | False
73 | ARMv7, ARM64
74 | True
75 | Automatic:AdHoc
76 | iPhone Developer
77 |
78 |
79 | none
80 | True
81 | bin\iPhone\AppStore
82 | prompt
83 | 4
84 | False
85 | ARMv7, ARM64
86 | Automatic:AppStore
87 | iPhone Distribution
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 | MyContacts
103 | {F7E62AA7-D013-43ED-A5DE-16792269C3BE}
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 | ..\packages\Xamarin.Forms.2.3.4.247\lib\Xamarin.iOS10\Xamarin.Forms.Core.dll
131 |
132 |
133 | ..\packages\Xamarin.Forms.2.3.4.247\lib\Xamarin.iOS10\Xamarin.Forms.Platform.dll
134 |
135 |
136 | ..\packages\Xamarin.Forms.2.3.4.247\lib\Xamarin.iOS10\Xamarin.Forms.Platform.iOS.dll
137 |
138 |
139 | ..\packages\Xamarin.Forms.2.3.4.247\lib\Xamarin.iOS10\Xamarin.Forms.Xaml.dll
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
--------------------------------------------------------------------------------
/MyContacts.iOS/MyContacts.iOS.csproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Simulator
5 | iPhone 7 iOS 11.2
6 |
7 |
--------------------------------------------------------------------------------
/MyContacts.iOS/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("MyContacts.iOS")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("MyContacts.iOS")]
13 | [assembly: AssemblyCopyright("Copyright © 2014")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("72bdc44f-c588-44f3-b6df-9aace7daafdd")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/MyContacts.iOS/Resources/Default-568h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canbilgin/DragAndDropSort/96652a7c21730f5b34f6773c7b5294b9b3adf95c/MyContacts.iOS/Resources/Default-568h@2x.png
--------------------------------------------------------------------------------
/MyContacts.iOS/Resources/Default-Portrait.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canbilgin/DragAndDropSort/96652a7c21730f5b34f6773c7b5294b9b3adf95c/MyContacts.iOS/Resources/Default-Portrait.png
--------------------------------------------------------------------------------
/MyContacts.iOS/Resources/Default-Portrait@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canbilgin/DragAndDropSort/96652a7c21730f5b34f6773c7b5294b9b3adf95c/MyContacts.iOS/Resources/Default-Portrait@2x.png
--------------------------------------------------------------------------------
/MyContacts.iOS/Resources/Default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canbilgin/DragAndDropSort/96652a7c21730f5b34f6773c7b5294b9b3adf95c/MyContacts.iOS/Resources/Default.png
--------------------------------------------------------------------------------
/MyContacts.iOS/Resources/Default@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canbilgin/DragAndDropSort/96652a7c21730f5b34f6773c7b5294b9b3adf95c/MyContacts.iOS/Resources/Default@2x.png
--------------------------------------------------------------------------------
/MyContacts.iOS/Resources/Icon-60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canbilgin/DragAndDropSort/96652a7c21730f5b34f6773c7b5294b9b3adf95c/MyContacts.iOS/Resources/Icon-60@2x.png
--------------------------------------------------------------------------------
/MyContacts.iOS/Resources/Icon-60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canbilgin/DragAndDropSort/96652a7c21730f5b34f6773c7b5294b9b3adf95c/MyContacts.iOS/Resources/Icon-60@3x.png
--------------------------------------------------------------------------------
/MyContacts.iOS/Resources/Icon-76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canbilgin/DragAndDropSort/96652a7c21730f5b34f6773c7b5294b9b3adf95c/MyContacts.iOS/Resources/Icon-76.png
--------------------------------------------------------------------------------
/MyContacts.iOS/Resources/Icon-76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canbilgin/DragAndDropSort/96652a7c21730f5b34f6773c7b5294b9b3adf95c/MyContacts.iOS/Resources/Icon-76@2x.png
--------------------------------------------------------------------------------
/MyContacts.iOS/Resources/Icon-Small-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canbilgin/DragAndDropSort/96652a7c21730f5b34f6773c7b5294b9b3adf95c/MyContacts.iOS/Resources/Icon-Small-40.png
--------------------------------------------------------------------------------
/MyContacts.iOS/Resources/Icon-Small-40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canbilgin/DragAndDropSort/96652a7c21730f5b34f6773c7b5294b9b3adf95c/MyContacts.iOS/Resources/Icon-Small-40@2x.png
--------------------------------------------------------------------------------
/MyContacts.iOS/Resources/Icon-Small-40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canbilgin/DragAndDropSort/96652a7c21730f5b34f6773c7b5294b9b3adf95c/MyContacts.iOS/Resources/Icon-Small-40@3x.png
--------------------------------------------------------------------------------
/MyContacts.iOS/Resources/Icon-Small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canbilgin/DragAndDropSort/96652a7c21730f5b34f6773c7b5294b9b3adf95c/MyContacts.iOS/Resources/Icon-Small.png
--------------------------------------------------------------------------------
/MyContacts.iOS/Resources/Icon-Small@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canbilgin/DragAndDropSort/96652a7c21730f5b34f6773c7b5294b9b3adf95c/MyContacts.iOS/Resources/Icon-Small@2x.png
--------------------------------------------------------------------------------
/MyContacts.iOS/Resources/Icon-Small@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canbilgin/DragAndDropSort/96652a7c21730f5b34f6773c7b5294b9b3adf95c/MyContacts.iOS/Resources/Icon-Small@3x.png
--------------------------------------------------------------------------------
/MyContacts.iOS/Resources/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/MyContacts.iOS/Resources/star.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canbilgin/DragAndDropSort/96652a7c21730f5b34f6773c7b5294b9b3adf95c/MyContacts.iOS/Resources/star.png
--------------------------------------------------------------------------------
/MyContacts.iOS/Resources/star@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canbilgin/DragAndDropSort/96652a7c21730f5b34f6773c7b5294b9b3adf95c/MyContacts.iOS/Resources/star@2x.png
--------------------------------------------------------------------------------
/MyContacts.iOS/iTunesArtwork:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canbilgin/DragAndDropSort/96652a7c21730f5b34f6773c7b5294b9b3adf95c/MyContacts.iOS/iTunesArtwork
--------------------------------------------------------------------------------
/MyContacts.iOS/iTunesArtwork@2x:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canbilgin/DragAndDropSort/96652a7c21730f5b34f6773c7b5294b9b3adf95c/MyContacts.iOS/iTunesArtwork@2x
--------------------------------------------------------------------------------
/MyContacts.iOS/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/MyContacts.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.26228.4
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyContacts", "MyContacts\MyContacts.csproj", "{F7E62AA7-D013-43ED-A5DE-16792269C3BE}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyContacts.iOS", "MyContacts.iOS\MyContacts.iOS.csproj", "{035E6526-E284-4E7C-8AC8-9A309BD1688A}"
9 | EndProject
10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyContacts.Droid", "MyContacts.Droid\MyContacts.Droid.csproj", "{AE4ADBDC-F8FD-47EC-935C-6EAD95335A40}"
11 | EndProject
12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyContacts.UWP", "MyContacts.UWP\MyContacts.UWP.csproj", "{5DD83C16-1132-4ACD-B9C4-93D9D33A4E0C}"
13 | EndProject
14 | Global
15 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
16 | Debug|Any CPU = Debug|Any CPU
17 | Debug|ARM = Debug|ARM
18 | Debug|x86 = Debug|x86
19 | Release|Any CPU = Release|Any CPU
20 | Release|ARM = Release|ARM
21 | Release|x86 = Release|x86
22 | EndGlobalSection
23 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
24 | {F7E62AA7-D013-43ED-A5DE-16792269C3BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
25 | {F7E62AA7-D013-43ED-A5DE-16792269C3BE}.Debug|Any CPU.Build.0 = Debug|Any CPU
26 | {F7E62AA7-D013-43ED-A5DE-16792269C3BE}.Debug|ARM.ActiveCfg = Debug|Any CPU
27 | {F7E62AA7-D013-43ED-A5DE-16792269C3BE}.Debug|ARM.Build.0 = Debug|Any CPU
28 | {F7E62AA7-D013-43ED-A5DE-16792269C3BE}.Debug|x86.ActiveCfg = Debug|Any CPU
29 | {F7E62AA7-D013-43ED-A5DE-16792269C3BE}.Debug|x86.Build.0 = Debug|Any CPU
30 | {F7E62AA7-D013-43ED-A5DE-16792269C3BE}.Release|Any CPU.ActiveCfg = Release|Any CPU
31 | {F7E62AA7-D013-43ED-A5DE-16792269C3BE}.Release|Any CPU.Build.0 = Release|Any CPU
32 | {F7E62AA7-D013-43ED-A5DE-16792269C3BE}.Release|ARM.ActiveCfg = Release|Any CPU
33 | {F7E62AA7-D013-43ED-A5DE-16792269C3BE}.Release|ARM.Build.0 = Release|Any CPU
34 | {F7E62AA7-D013-43ED-A5DE-16792269C3BE}.Release|x86.ActiveCfg = Release|Any CPU
35 | {F7E62AA7-D013-43ED-A5DE-16792269C3BE}.Release|x86.Build.0 = Release|Any CPU
36 | {035E6526-E284-4E7C-8AC8-9A309BD1688A}.Debug|Any CPU.ActiveCfg = Debug|iPhoneSimulator
37 | {035E6526-E284-4E7C-8AC8-9A309BD1688A}.Debug|Any CPU.Build.0 = Debug|iPhoneSimulator
38 | {035E6526-E284-4E7C-8AC8-9A309BD1688A}.Debug|ARM.ActiveCfg = Debug|iPhone
39 | {035E6526-E284-4E7C-8AC8-9A309BD1688A}.Debug|ARM.Build.0 = Debug|iPhone
40 | {035E6526-E284-4E7C-8AC8-9A309BD1688A}.Debug|x86.ActiveCfg = Debug|iPhoneSimulator
41 | {035E6526-E284-4E7C-8AC8-9A309BD1688A}.Debug|x86.Build.0 = Debug|iPhoneSimulator
42 | {035E6526-E284-4E7C-8AC8-9A309BD1688A}.Release|Any CPU.ActiveCfg = Release|iPhoneSimulator
43 | {035E6526-E284-4E7C-8AC8-9A309BD1688A}.Release|Any CPU.Build.0 = Release|iPhoneSimulator
44 | {035E6526-E284-4E7C-8AC8-9A309BD1688A}.Release|ARM.ActiveCfg = Release|iPhone
45 | {035E6526-E284-4E7C-8AC8-9A309BD1688A}.Release|ARM.Build.0 = Release|iPhone
46 | {035E6526-E284-4E7C-8AC8-9A309BD1688A}.Release|x86.ActiveCfg = Release|iPhoneSimulator
47 | {035E6526-E284-4E7C-8AC8-9A309BD1688A}.Release|x86.Build.0 = Release|iPhoneSimulator
48 | {AE4ADBDC-F8FD-47EC-935C-6EAD95335A40}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
49 | {AE4ADBDC-F8FD-47EC-935C-6EAD95335A40}.Debug|Any CPU.Build.0 = Debug|Any CPU
50 | {AE4ADBDC-F8FD-47EC-935C-6EAD95335A40}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
51 | {AE4ADBDC-F8FD-47EC-935C-6EAD95335A40}.Debug|ARM.ActiveCfg = Debug|Any CPU
52 | {AE4ADBDC-F8FD-47EC-935C-6EAD95335A40}.Debug|ARM.Build.0 = Debug|Any CPU
53 | {AE4ADBDC-F8FD-47EC-935C-6EAD95335A40}.Debug|ARM.Deploy.0 = Debug|Any CPU
54 | {AE4ADBDC-F8FD-47EC-935C-6EAD95335A40}.Debug|x86.ActiveCfg = Debug|Any CPU
55 | {AE4ADBDC-F8FD-47EC-935C-6EAD95335A40}.Debug|x86.Build.0 = Debug|Any CPU
56 | {AE4ADBDC-F8FD-47EC-935C-6EAD95335A40}.Debug|x86.Deploy.0 = Debug|Any CPU
57 | {AE4ADBDC-F8FD-47EC-935C-6EAD95335A40}.Release|Any CPU.ActiveCfg = Release|Any CPU
58 | {AE4ADBDC-F8FD-47EC-935C-6EAD95335A40}.Release|Any CPU.Build.0 = Release|Any CPU
59 | {AE4ADBDC-F8FD-47EC-935C-6EAD95335A40}.Release|Any CPU.Deploy.0 = Release|Any CPU
60 | {AE4ADBDC-F8FD-47EC-935C-6EAD95335A40}.Release|ARM.ActiveCfg = Release|Any CPU
61 | {AE4ADBDC-F8FD-47EC-935C-6EAD95335A40}.Release|ARM.Build.0 = Release|Any CPU
62 | {AE4ADBDC-F8FD-47EC-935C-6EAD95335A40}.Release|ARM.Deploy.0 = Release|Any CPU
63 | {AE4ADBDC-F8FD-47EC-935C-6EAD95335A40}.Release|x86.ActiveCfg = Release|Any CPU
64 | {AE4ADBDC-F8FD-47EC-935C-6EAD95335A40}.Release|x86.Build.0 = Release|Any CPU
65 | {AE4ADBDC-F8FD-47EC-935C-6EAD95335A40}.Release|x86.Deploy.0 = Release|Any CPU
66 | {5DD83C16-1132-4ACD-B9C4-93D9D33A4E0C}.Debug|Any CPU.ActiveCfg = Debug|x86
67 | {5DD83C16-1132-4ACD-B9C4-93D9D33A4E0C}.Debug|Any CPU.Build.0 = Debug|x86
68 | {5DD83C16-1132-4ACD-B9C4-93D9D33A4E0C}.Debug|Any CPU.Deploy.0 = Debug|x86
69 | {5DD83C16-1132-4ACD-B9C4-93D9D33A4E0C}.Debug|ARM.ActiveCfg = Debug|ARM
70 | {5DD83C16-1132-4ACD-B9C4-93D9D33A4E0C}.Debug|ARM.Build.0 = Debug|ARM
71 | {5DD83C16-1132-4ACD-B9C4-93D9D33A4E0C}.Debug|ARM.Deploy.0 = Debug|ARM
72 | {5DD83C16-1132-4ACD-B9C4-93D9D33A4E0C}.Debug|x86.ActiveCfg = Debug|x86
73 | {5DD83C16-1132-4ACD-B9C4-93D9D33A4E0C}.Debug|x86.Build.0 = Debug|x86
74 | {5DD83C16-1132-4ACD-B9C4-93D9D33A4E0C}.Debug|x86.Deploy.0 = Debug|x86
75 | {5DD83C16-1132-4ACD-B9C4-93D9D33A4E0C}.Release|Any CPU.ActiveCfg = Release|x86
76 | {5DD83C16-1132-4ACD-B9C4-93D9D33A4E0C}.Release|Any CPU.Build.0 = Release|x86
77 | {5DD83C16-1132-4ACD-B9C4-93D9D33A4E0C}.Release|Any CPU.Deploy.0 = Release|x86
78 | {5DD83C16-1132-4ACD-B9C4-93D9D33A4E0C}.Release|ARM.ActiveCfg = Release|ARM
79 | {5DD83C16-1132-4ACD-B9C4-93D9D33A4E0C}.Release|ARM.Build.0 = Release|ARM
80 | {5DD83C16-1132-4ACD-B9C4-93D9D33A4E0C}.Release|ARM.Deploy.0 = Release|ARM
81 | {5DD83C16-1132-4ACD-B9C4-93D9D33A4E0C}.Release|x86.ActiveCfg = Release|x86
82 | {5DD83C16-1132-4ACD-B9C4-93D9D33A4E0C}.Release|x86.Build.0 = Release|x86
83 | {5DD83C16-1132-4ACD-B9C4-93D9D33A4E0C}.Release|x86.Deploy.0 = Release|x86
84 | EndGlobalSection
85 | GlobalSection(SolutionProperties) = preSolution
86 | HideSolutionNode = FALSE
87 | EndGlobalSection
88 | EndGlobal
89 |
--------------------------------------------------------------------------------
/MyContacts/AllContacts.xaml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
32 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
--------------------------------------------------------------------------------
/MyContacts/AllContacts.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | using Xamarin.Forms;
8 | using System.Threading;
9 | using System.Windows.Input;
10 | using System.ComponentModel;
11 | using System.Collections.ObjectModel;
12 |
13 | namespace MyContacts
14 | {
15 | public partial class AllContacts : ContentPage
16 | {
17 | public AllContacts()
18 | {
19 | InitializeComponent();
20 |
21 | BindingContext = new AllContactsViewModel();
22 |
23 | allContacts.BindingContextChanged += (sender, e) => {
24 | var change = e;
25 | };
26 |
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/MyContacts/AllContactsViewModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel;
3 | using System.Runtime.CompilerServices;
4 | using System.Collections.Generic;
5 | using System.Collections.Specialized;
6 | using System.Windows.Input;
7 | using Xamarin.Forms;
8 | using System.Linq;
9 | using System.Collections.ObjectModel;
10 | using System.Threading.Tasks;
11 |
12 | namespace MyContacts
13 | {
14 | public interface IPlayerService
15 | {
16 | Task> GetPlayersAsync();
17 | }
18 |
19 | public class PlayersService : IPlayerService
20 | {
21 | private List _contacts = new List();
22 |
23 | int callCount = 0;
24 |
25 | public Task> GetPlayersAsync()
26 | {
27 | if (!_contacts.Any())
28 | {
29 | _contacts = new List(PlayerFactory.Players);
30 | }
31 | else
32 | {
33 | AddPlayer();
34 | }
35 |
36 | //_contacts[callCount++].Position += "-Updated";
37 |
38 | return Task.FromResult(new List(_contacts.Select(item=>item.Clone())) as IEnumerable);
39 | }
40 |
41 | IEnumerator _enumerator = null;
42 |
43 | private void AddPlayer()
44 | {
45 | if (_enumerator == null)
46 | {
47 | _enumerator = PlayerFactory.GetPlayer().GetEnumerator();
48 | _enumerator.MoveNext();
49 | }
50 |
51 | _contacts.Add(_enumerator.Current);
52 |
53 | //SetProperty(ref _allContacts, new List(AllContacts), nameof(AllContacts));
54 |
55 | _enumerator.MoveNext();
56 | }
57 | }
58 |
59 | public class AllContactsViewModel: ObservableObject
60 | {
61 | private ObservableListCollection _allContacts = new ObservableListCollection();
62 |
63 | private IEnumerable> _groupedContacts = null;
64 |
65 | private ObservableListGroupCollection _grouppedCollection = null;
66 |
67 | private PlayersService _service = new PlayersService();
68 |
69 | private Command _editCommand;
70 |
71 | private Command _updateCommand;
72 |
73 | private bool _allowOrdering;
74 |
75 | public IEnumerable> GroupedContacts {
76 | get
77 | {
78 | return _groupedContacts;
79 | }
80 | set
81 | {
82 | SetProperty(ref _groupedContacts, value);
83 | }
84 | }
85 |
86 | public ObservableListGroupCollection GroupedCollection
87 | {
88 | get
89 | {
90 | return _grouppedCollection;
91 | }
92 | set
93 | {
94 | SetProperty(ref _grouppedCollection, value);
95 | }
96 | }
97 |
98 | public ObservableListCollection AllContacts
99 | {
100 | get
101 | {
102 | return _allContacts;
103 | }
104 | set
105 | {
106 | SetProperty(ref _allContacts, value);
107 | }
108 | }
109 |
110 | public bool AllowOrdering
111 | {
112 | get
113 | {
114 | return _allowOrdering;
115 | }
116 | set
117 | {
118 | SetProperty(ref _allowOrdering, value);
119 | }
120 | }
121 |
122 | public ICommand EditCommand
123 | {
124 | get
125 | {
126 | return _editCommand;
127 | }
128 | }
129 |
130 | public ICommand UpdateCommand
131 | {
132 | get
133 | {
134 | return _updateCommand;
135 | }
136 | }
137 |
138 | public AllContactsViewModel()
139 | {
140 | _editCommand = new Command(() => { AllowOrdering = !AllowOrdering; });
141 | _updateCommand = new Command(async () => await UpdatePlayers());
142 |
143 | _allContacts = new ObservableListCollection(Enumerable.Empty(), new PersonNameComparer(), (person, update) =>
144 | {
145 | person.LoadData(update);
146 | return true;
147 | });
148 |
149 | _allContacts.OrderChanged += (sender, e) => {
150 | int jersey = 1;
151 | foreach(var item in _allContacts)
152 | {
153 | item.Jersey = jersey++;
154 | }
155 | };
156 |
157 | _grouppedCollection = new ObservableListGroupCollection(
158 | Enumerable.Empty(),
159 | item => item.Position,
160 | new PersonNameComparer(),
161 | (person, update) =>
162 | {
163 | person.LoadData(update);
164 | return true;
165 | });
166 |
167 | UpdatePlayers().ConfigureAwait(false);
168 | }
169 |
170 | private async Task UpdatePlayers()
171 | {
172 | IEnumerable serviceResult = Enumerable.Empty();
173 |
174 | try
175 | {
176 | serviceResult = await _service.GetPlayersAsync();
177 | }
178 | catch(Exception ex)
179 | {
180 | // TODO:
181 | }
182 |
183 | if(serviceResult?.Any()??false)
184 | {
185 | _allContacts.UpdateRange(serviceResult);
186 |
187 | GroupedContacts = serviceResult.GroupBy(item => item.Position);
188 | GroupedCollection.UpdateItems(serviceResult);
189 | //var newItems = serviceResult.Where(item => !AllContacts.Any(contact => item.Name == contact.Name));
190 |
191 | //var updatedItems = serviceResult.Where(item => AllContacts.Any(contact => item.Name == contact.Name));
192 |
193 | //foreach (var updateItem in updatedItems)
194 | //{
195 | // var existingItem = AllContacts.FirstOrDefault(contact => contact.Name == updateItem.Name);
196 | // existingItem.LoadData(updateItem);
197 | //}
198 |
199 | //foreach(var item in newItems)
200 | //{
201 | // AllContacts.Add(item);
202 | //}
203 | }
204 | }
205 |
206 | int updateCount = 0;
207 |
208 | private void UpdatePlayer()
209 | {
210 | AllContacts[updateCount].Position = AllContacts[updateCount].Position + "(Updated)";
211 |
212 | if (updateCount++ > 10)
213 | {
214 | updateCount = 0;
215 | }
216 | }
217 | }
218 |
219 | ///
220 | /// Observable object with INotifyPropertyChanged implemented
221 | ///
222 | public class ObservableObject : INotifyPropertyChanged
223 | {
224 |
225 | ///
226 | /// Occurs when property changed.
227 | ///
228 | public event PropertyChangedEventHandler PropertyChanged;
229 |
230 | ///
231 | /// Sets the property.
232 | ///
233 | /// true, if property was set, false otherwise.
234 | /// Backing store.
235 | /// Incoming new value.
236 | /// Property name.
237 | /// On changed.
238 | /// The 1st type parameter.
239 | protected bool SetProperty(
240 | ref T backingStore,
241 | T value,
242 | [CallerMemberName]string propertyName = "",
243 | Action onChanged = null)
244 | {
245 | if (EqualityComparer.Default.Equals(backingStore, value))
246 | {
247 | return false;
248 | }
249 |
250 | backingStore = value;
251 | onChanged?.Invoke();
252 | OnPropertyChanged(propertyName);
253 | return true;
254 | }
255 |
256 | ///
257 | /// Raises the property changed event.
258 | ///
259 | /// Property name.
260 | protected void OnPropertyChanged([CallerMemberName]string propertyName = "")
261 | {
262 | PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
263 | }
264 | }
265 | }
266 |
--------------------------------------------------------------------------------
/MyContacts/App.cs:
--------------------------------------------------------------------------------
1 | using Xamarin.Forms;
2 | using System.Linq;
3 |
4 | namespace MyContacts
5 | {
6 | public class App : Application
7 | {
8 | public App()
9 | {
10 | MainPage = new NavigationPage(new AllContacts());
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/MyContacts/ContactDetails.xaml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 | Male
34 | Female
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/MyContacts/ContactDetails.xaml.cs:
--------------------------------------------------------------------------------
1 | using Xamarin.Forms;
2 |
3 | namespace MyContacts
4 | {
5 | public partial class ContactDetails : ContentPage
6 | {
7 | public ContactDetails(Person person)
8 | {
9 | BindingContext = person;
10 | InitializeComponent();
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/MyContacts/Converters/BirthdayConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Xamarin.Forms;
3 |
4 | namespace MyContacts
5 | {
6 | ///
7 | /// Simple converter to take a DateTime and calculate how many years old it represents.
8 | ///
9 | public class BirthdayConverter : IValueConverter
10 | {
11 | public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
12 | {
13 | DateTime bday = (DateTime)value;
14 | DateTime today = DateTime.Today;
15 | int age = today.Year - bday.Year;
16 | return (bday > today.AddYears(-age)) ? age-1 : age;
17 | }
18 |
19 | public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
20 | {
21 | throw new NotImplementedException();
22 | }
23 | }
24 | }
25 |
26 |
--------------------------------------------------------------------------------
/MyContacts/Converters/GenderToIndexConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Xamarin.Forms;
3 | using System.Globalization;
4 |
5 | namespace MyContacts
6 | {
7 | public class GenderToIndexConverter : IValueConverter
8 | {
9 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
10 | {
11 | Gender gender = (Gender)value;
12 | if (targetType != typeof(int))
13 | throw new Exception("GenderConverter.Convert expected integer targetType.");
14 | return (int)gender;
15 | }
16 |
17 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
18 | {
19 | int index = (int)value;
20 | if (targetType != typeof(Gender))
21 | throw new Exception("GenderConverter.ConvertBack expected Gender targetType");
22 | return (Gender)index;
23 | }
24 | }
25 |
26 | ///
27 | /// Simple converter to take a DateTime and calculate how many years old it represents.
28 | ///
29 | public class BirthdayConverter : IValueConverter
30 | {
31 | public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
32 | {
33 | DateTime bday = (DateTime)value;
34 | DateTime today = DateTime.Today;
35 | int age = today.Year - bday.Year;
36 | return (bday > today.AddYears(-age)) ? age - 1 : age;
37 | }
38 |
39 | public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
40 | {
41 | throw new NotImplementedException();
42 | } }
43 | }
44 |
45 |
--------------------------------------------------------------------------------
/MyContacts/Converters/ImageResourceConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Xamarin.Forms;
3 |
4 | namespace MyContacts
5 | {
6 | public class ImageResourceConverter : IValueConverter
7 | {
8 | public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
9 | {
10 | return ImageSource.FromUri(new Uri("https://tmssl.akamaized.net//images/portrait/header/" + (value ?? "")));
11 | }
12 |
13 | public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
14 | {
15 | throw new NotSupportedException();
16 | }
17 | }
18 | }
19 |
20 |
--------------------------------------------------------------------------------
/MyContacts/Data/Gender.cs:
--------------------------------------------------------------------------------
1 | namespace MyContacts
2 | {
3 | public enum Gender { Male, Female };
4 |
5 | }
6 |
--------------------------------------------------------------------------------
/MyContacts/Data/Person.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Runtime.CompilerServices;
5 |
6 | namespace MyContacts
7 | {
8 | public class PersonNameComparer : IEqualityComparer
9 | {
10 | public bool Equals(Person x, Person y)
11 | {
12 | return x.Name == y.Name;
13 | }
14 |
15 | public int GetHashCode(Person obj)
16 | {
17 | throw new NotImplementedException();
18 | }
19 | }
20 |
21 | public class Person : INotifyPropertyChanged
22 | {
23 | private string name;
24 |
25 | private string position;
26 |
27 | private DateTime dob;
28 |
29 | private Gender gender;
30 |
31 | private bool isFavorite;
32 |
33 | private int _jersey;
34 |
35 | public event PropertyChangedEventHandler PropertyChanged = delegate {};
36 |
37 | public string HeadshotUrl { get; set; }
38 |
39 | public string Name {
40 | get { return name; }
41 | set { SetProperty(ref name, value); }
42 | }
43 |
44 | public string Position
45 | {
46 | get { return position; }
47 | set { SetProperty(ref position, value); }
48 | }
49 |
50 | public DateTime Dob {
51 | get { return dob; }
52 | set { SetProperty(ref dob, value); }
53 | }
54 |
55 | public Gender Gender {
56 | get { return gender; }
57 | set { SetProperty(ref gender, value); }
58 | }
59 |
60 | public bool IsFavorite {
61 | get { return isFavorite; }
62 | set { SetProperty(ref isFavorite, value); }
63 | }
64 |
65 | public int Jersey
66 | {
67 | get { return _jersey; }
68 | set { SetProperty(ref _jersey, value); }
69 | }
70 |
71 | ///
72 | /// Method to compare and replace a field's value and raise a
73 | /// PropertyChanged notification if it was altered.
74 | ///
75 | /// true, if field was set, false otherwise.
76 | /// Field.
77 | /// Value.
78 | /// Property name.
79 | /// Field type.
80 | bool SetProperty(ref T field, T value, [CallerMemberName] string propertyName = "")
81 | {
82 | if (!object.Equals(field, value)) {
83 | field = value;
84 | PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
85 | return true;
86 | }
87 | return false;
88 | }
89 |
90 | public override string ToString()
91 | {
92 | return this.Name;
93 | }
94 |
95 | internal void LoadData(Person item)
96 | {
97 | Position = item.Position;
98 | Dob = item.Dob;
99 | Gender = item.Gender;
100 | Jersey = item.Jersey;
101 | IsFavorite = item.IsFavorite;
102 | HeadshotUrl = item.HeadshotUrl;
103 | }
104 |
105 | internal Person Clone()
106 | {
107 | var target = new Person();
108 | target.Name = Name;
109 | target.LoadData(this);
110 |
111 | return target;
112 | }
113 | }
114 |
115 | }
116 |
--------------------------------------------------------------------------------
/MyContacts/Data/PlayerFactory.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Collections.ObjectModel;
4 |
5 | namespace MyContacts
6 | {
7 | public static class PlayerFactory
8 | {
9 | public static IList Players { get; private set; }
10 |
11 | public static IEnumerable GetPlayer()
12 | {
13 | yield return new Person
14 | {
15 | Name = "Souza",
16 | HeadshotUrl = "73741-1473554668.jpg?lm=1473554751",
17 | Position = "Midfield",
18 | Dob = new DateTime(1989, 2, 11),
19 | IsFavorite = false,
20 | Jersey = 7
21 | };
22 | yield return new Person
23 | {
24 | Name = "Jermaine Lens",
25 | HeadshotUrl = "38497-1473555279.jpg?lm=1473555301",
26 | Position = "Midfield",
27 | Dob = new DateTime(1987, 10, 24),
28 | IsFavorite = false,
29 | Jersey = 8
30 | };
31 | yield return new Person
32 | {
33 | Name = "Miroslav Stoch",
34 | HeadshotUrl = "45559-1473555016.jpg?lm=1473555042",
35 | Position = "Midfield",
36 | Dob = new DateTime(1989, 10, 19),
37 | IsFavorite = false,
38 | Jersey = 9
39 | };
40 | yield return new Person
41 | {
42 | Name = "Moussa Sow",
43 | HeadshotUrl = "22382-1473555184.jpg?lm=1473555202",
44 | Position = "Forward",
45 | Dob = new DateTime(1986, 01, 19),
46 | IsFavorite = false,
47 | Jersey = 10
48 | };
49 | yield return new Person
50 | {
51 | Name = "Robin van Persie",
52 | HeadshotUrl = "4380-1473555404.jpg?lm=1473555436",
53 | Position = "Forward",
54 | Dob = new DateTime(1983, 9, 6),
55 | IsFavorite = false,
56 | Jersey = 11
57 | };
58 | }
59 |
60 | static PlayerFactory()
61 | {
62 | Players = new List
63 | {
64 | new Person
65 | {
66 | Name = "Volkan Demirel",
67 | HeadshotUrl = "7079-1473554155.jpg?lm=1473554223",
68 | Position = "Keeper",
69 | Dob = new DateTime(1981, 11, 27),
70 | IsFavorite = false,
71 | Jersey = 1
72 | },
73 | new Person
74 | {
75 | Name = "Simon Kjaer",
76 | HeadshotUrl = "48859-1473554328.jpg?lm=1473554361",
77 | Position = "Defender",
78 | Dob = new DateTime(1989, 3, 26),
79 | IsFavorite = true,
80 | Jersey = 2
81 | },
82 | new Person
83 | {
84 | Name = "Martin Skrtel",
85 | HeadshotUrl = "24180-1473554340.jpg?lm=1473554385",
86 | Position = "Defender",
87 | Dob = new DateTime(1984, 12, 15),
88 | IsFavorite = true,
89 | Jersey = 3
90 | },
91 | new Person
92 | {
93 | Name = "Hasan Ali Kaldirim",
94 | HeadshotUrl = "55605-1473554474.jpg?lm=1473554515",
95 | Position = "Defender",
96 | Dob = new DateTime(1989, 12, 9),
97 | IsFavorite = true,
98 | Jersey = 4
99 | },
100 |
101 | new Person
102 | {
103 | Name = "Sezer Ozbayrakli",
104 | HeadshotUrl = "169873-1473554503.jpg?lm=1473554574",
105 | Position = "Defender",
106 | Dob = new DateTime(1990, 01, 23),
107 | IsFavorite = false,
108 | Jersey = 5
109 | },
110 |
111 | new Person
112 | {
113 | Name = "Mehmet Topal",
114 | HeadshotUrl = "44402-1473554660.jpg?lm=1473554723",
115 | Position = "Defensive Midfield",
116 | Dob = new DateTime(1986, 3, 3),
117 | IsFavorite = false,
118 | Jersey = 6
119 | }
120 | };
121 | }
122 | }
123 | }
124 |
125 |
--------------------------------------------------------------------------------
/MyContacts/Effects/DropShadowEffect.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using Xamarin.Forms;
4 |
5 | namespace MyContacts.Effects
6 | {
7 | public class ViewShadowEffect : RoutingEffect
8 | {
9 | public float Radius { get; set; }
10 |
11 | public Color Color { get; set; }
12 |
13 | public float DistanceX { get; set; }
14 |
15 | public float DistanceY { get; set; }
16 |
17 | public ViewShadowEffect() : base("CubiSoft.DropShadowEffect")
18 | {
19 | }
20 | }
21 |
22 | public static class Sorting
23 | {
24 | public static readonly BindableProperty IsSortableProperty =
25 | BindableProperty.CreateAttached("IsSortable", typeof(bool), typeof(ListViewSortableEffect), false,
26 | propertyChanged: OnIsSortableChanged);
27 |
28 | public static bool GetIsSortable(BindableObject view)
29 | {
30 | return (bool)view.GetValue(IsSortableProperty);
31 | }
32 |
33 | public static void SetIsSortable(BindableObject view, bool value)
34 | {
35 | view.SetValue(IsSortableProperty, value);
36 | }
37 |
38 | static void OnIsSortableChanged(BindableObject bindable, object oldValue, object newValue)
39 | {
40 | var view = bindable as ListView;
41 | if (view == null)
42 | {
43 | return;
44 | }
45 |
46 | if (!view.Effects.Any(item => item is ListViewSortableEffect))
47 | {
48 | view.Effects.Add(new ListViewSortableEffect());
49 | }
50 | }
51 |
52 | class ListViewSortableEffect : RoutingEffect
53 | {
54 | public ListViewSortableEffect() : base("CubiSoft.ListViewSortableEffect")
55 | {
56 |
57 | }
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/MyContacts/Images/Apu.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canbilgin/DragAndDropSort/96652a7c21730f5b34f6773c7b5294b9b3adf95c/MyContacts/Images/Apu.gif
--------------------------------------------------------------------------------
/MyContacts/Images/Bart.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canbilgin/DragAndDropSort/96652a7c21730f5b34f6773c7b5294b9b3adf95c/MyContacts/Images/Bart.gif
--------------------------------------------------------------------------------
/MyContacts/Images/ComicBookGuy.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canbilgin/DragAndDropSort/96652a7c21730f5b34f6773c7b5294b9b3adf95c/MyContacts/Images/ComicBookGuy.gif
--------------------------------------------------------------------------------
/MyContacts/Images/Homer.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canbilgin/DragAndDropSort/96652a7c21730f5b34f6773c7b5294b9b3adf95c/MyContacts/Images/Homer.gif
--------------------------------------------------------------------------------
/MyContacts/Images/Krusty.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canbilgin/DragAndDropSort/96652a7c21730f5b34f6773c7b5294b9b3adf95c/MyContacts/Images/Krusty.gif
--------------------------------------------------------------------------------
/MyContacts/Images/Lisa.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canbilgin/DragAndDropSort/96652a7c21730f5b34f6773c7b5294b9b3adf95c/MyContacts/Images/Lisa.gif
--------------------------------------------------------------------------------
/MyContacts/Images/Maggie.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canbilgin/DragAndDropSort/96652a7c21730f5b34f6773c7b5294b9b3adf95c/MyContacts/Images/Maggie.gif
--------------------------------------------------------------------------------
/MyContacts/Images/Marge.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canbilgin/DragAndDropSort/96652a7c21730f5b34f6773c7b5294b9b3adf95c/MyContacts/Images/Marge.gif
--------------------------------------------------------------------------------
/MyContacts/Images/Milhouse.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canbilgin/DragAndDropSort/96652a7c21730f5b34f6773c7b5294b9b3adf95c/MyContacts/Images/Milhouse.gif
--------------------------------------------------------------------------------
/MyContacts/Images/MoeSzyslak.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canbilgin/DragAndDropSort/96652a7c21730f5b34f6773c7b5294b9b3adf95c/MyContacts/Images/MoeSzyslak.gif
--------------------------------------------------------------------------------
/MyContacts/Images/MrBurns.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canbilgin/DragAndDropSort/96652a7c21730f5b34f6773c7b5294b9b3adf95c/MyContacts/Images/MrBurns.gif
--------------------------------------------------------------------------------
/MyContacts/Images/SideshowBob.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canbilgin/DragAndDropSort/96652a7c21730f5b34f6773c7b5294b9b3adf95c/MyContacts/Images/SideshowBob.gif
--------------------------------------------------------------------------------
/MyContacts/Images/WaylonSmithers.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canbilgin/DragAndDropSort/96652a7c21730f5b34f6773c7b5294b9b3adf95c/MyContacts/Images/WaylonSmithers.gif
--------------------------------------------------------------------------------
/MyContacts/MyContacts.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 10.0
6 | Debug
7 | AnyCPU
8 | {F7E62AA7-D013-43ED-A5DE-16792269C3BE}
9 | Library
10 | Properties
11 | MyContacts
12 | MyContacts
13 | v4.5
14 | Profile259
15 | 512
16 | {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
17 |
18 |
19 |
20 |
21 | true
22 | full
23 | false
24 | bin\Debug\
25 | DEBUG;TRACE
26 | prompt
27 | 4
28 |
29 |
30 | pdbonly
31 | true
32 | bin\Release\
33 | TRACE
34 | prompt
35 | 4
36 |
37 |
38 |
39 | AllContacts.xaml
40 |
41 |
42 |
43 | ContactDetails.xaml
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 | Designer
58 | MSBuild:UpdateDesignTimeXaml
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 | MSBuild:UpdateDesignTimeXaml
79 | Designer
80 |
81 |
82 |
83 |
84 |
85 | ..\packages\Xamarin.Forms.2.3.4.247\lib\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+Xamarin.iOS10+xamarinmac20\Xamarin.Forms.Core.dll
86 |
87 |
88 | ..\packages\Xamarin.Forms.2.3.4.247\lib\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+Xamarin.iOS10+xamarinmac20\Xamarin.Forms.Platform.dll
89 |
90 |
91 | ..\packages\Xamarin.Forms.2.3.4.247\lib\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+Xamarin.iOS10+xamarinmac20\Xamarin.Forms.Xaml.dll
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
--------------------------------------------------------------------------------
/MyContacts/MyFacade.SecondPart.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace MyContacts
8 | {
9 | public partial class MyFacade : IFacade
10 | {
11 | public void Method4()
12 | {
13 | throw new NotImplementedException();
14 | }
15 |
16 | public void Method5()
17 | {
18 | throw new NotImplementedException();
19 | }
20 |
21 | public void Method6()
22 | {
23 | throw new NotImplementedException();
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/MyContacts/MyFacade.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace MyContacts
8 | {
9 | public interface IFacade
10 | {
11 | void Method1();
12 | void Method2();
13 | void Method3();
14 | void Method4();
15 | void Method5();
16 | void Method6();
17 | }
18 |
19 | public partial class MyFacade : IFacade
20 | {
21 | public void Method1()
22 | {
23 | throw new NotImplementedException();
24 | }
25 |
26 | public void Method2()
27 | {
28 | throw new NotImplementedException();
29 | }
30 |
31 | public void Method3()
32 | {
33 | throw new NotImplementedException();
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/MyContacts/ObservableListCollection.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Collections.ObjectModel;
4 | using System.Collections.Specialized;
5 | using System.ComponentModel;
6 | using System.Linq;
7 |
8 | namespace MyContacts
9 | {
10 | public class ObservableListGroupCollection : ObservableListCollection>
11 | {
12 | private Func _groupKeySelector;
13 |
14 | private IEqualityComparer _equivalenceComparer;
15 |
16 | private Func _updateFunction;
17 |
18 | public ObservableListGroupCollection(
19 | IEnumerable collection,
20 | Func keySelector,
21 | IEqualityComparer equivalence = null,
22 | Func updateCallback = null)
23 | {
24 | _groupKeySelector = keySelector;
25 | _equivalenceComparer = equivalence;
26 | _updateFunction = updateCallback;
27 |
28 | UpdateItems(collection);
29 | }
30 |
31 | public void UpdateItems(IEnumerable items)
32 | {
33 | var grouppedItems = items.GroupBy(_groupKeySelector);
34 |
35 | var startIndex = Count;
36 |
37 | var newItems = new List>();
38 |
39 | foreach (var group in grouppedItems)
40 | {
41 | var section = Items.FirstOrDefault(item => item.Key.Equals(group.Key));
42 |
43 | if (section == null)
44 | {
45 | var newGroup = new ObservableListGroup(group.Key, group, _equivalenceComparer, _updateFunction);
46 | newItems.Add(newGroup);
47 | Items.Add(newGroup);
48 | }
49 | else
50 | {
51 | section.UpdateRange(group);
52 | }
53 | }
54 |
55 | if (newItems.Any())
56 | {
57 | OnPropertyChanged(new PropertyChangedEventArgs("Count"));
58 | OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, newItems, startIndex));
59 | }
60 | }
61 | }
62 |
63 | ///
64 | /// Grouping of items
65 | ///
66 | public class ObservableListGroup : ObservableListCollection
67 | {
68 | public TKey Key { get; }
69 |
70 | public ObservableListGroup(TKey key, IEnumerable items, IEqualityComparer equivalence = null, Func updateCallback = null)
71 | : base(Enumerable.Empty(), equivalence, updateCallback)
72 | {
73 | Key = key;
74 | UpdateRange(items);
75 | }
76 | }
77 |
78 | ///
79 | /// Used by bound collections to expose ordering methods/events
80 | ///
81 | public interface IOrderable
82 | {
83 | ///
84 | /// Event fired when the items in the collection are re-ordered.
85 | ///
86 | event EventHandler OrderChanged;
87 |
88 | ///
89 | /// Used to change the item orders in an enumerable
90 | ///
91 | ///
92 | /// The old index of the item.
93 | ///
94 | ///
95 | /// The new index of the item.
96 | ///
97 | void ChangeOrdinal(int oldIndex, int newIndex);
98 | }
99 |
100 | ///
101 | /// ObservableCollection implementation for updating and adding items
102 | ///
103 | /// Entity type
104 | public class ObservableListCollection : ObservableCollection, IOrderable
105 | {
106 | private IEqualityComparer _equivalenceComparer;
107 |
108 | private Func _updateFunction;
109 |
110 | ///
111 | /// Initializes a new instance of the class.
112 | ///
113 | public ObservableListCollection() : base()
114 | {
115 | }
116 | public event EventHandler OrderChanged;
117 |
118 | public void ChangeOrdinal(int oldIndex, int newIndex)
119 | {
120 | var priorIndex = oldIndex;
121 | var latterIndex = newIndex;
122 |
123 | var changedItem = Items[oldIndex];
124 | if (newIndex < oldIndex)
125 | {
126 | // add one to where we delete, because we're increasing the index by inserting
127 | priorIndex += 1;
128 | }
129 | else
130 | {
131 | // add one to where we insert, because we haven't deleted the original yet
132 | latterIndex += 1;
133 | }
134 |
135 | Items.Insert(latterIndex, changedItem);
136 | Items.RemoveAt(priorIndex);
137 |
138 | OrderChanged?.Invoke(this, EventArgs.Empty);
139 |
140 | OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Move, changedItem, newIndex, oldIndex));
141 | }
142 |
143 | ///
144 | /// Initializes a new instance of the class.
145 | ///
146 | /// collection: The collection from which the elements are copied.
147 | /// The collection parameter cannot be null.
148 | public ObservableListCollection(IEnumerable collection, IEqualityComparer equivalence = null, Func updateCallback = null)
149 | : base(collection)
150 | {
151 | _equivalenceComparer = equivalence ?? EqualityComparer.Default;
152 | _updateFunction = updateCallback;
153 | }
154 |
155 | ///
156 | /// Updates or adds the elements of the specified collection to the end of the ObservableCollection(Of T).
157 | ///
158 | ///
159 | /// The collection to be added.
160 | ///
161 | public void UpdateRange(IEnumerable collection)
162 | {
163 | if (collection == null)
164 | {
165 | throw new ArgumentNullException(nameof(collection));
166 | }
167 |
168 | CheckReentrancy();
169 |
170 | int startIndex = Count;
171 |
172 | var updatedItems = collection.Where(item => Items.Any(contact => _equivalenceComparer.Equals(contact, item))).ToList();
173 |
174 | bool anyItemUpdated = false;
175 |
176 | foreach (var updateItem in updatedItems)
177 | {
178 | var existingItem = Items.FirstOrDefault(contact => _equivalenceComparer.Equals(contact, updateItem));
179 |
180 | // TODO: We can fire NotifyCollectionChanged.Update if needed depending on anyItemUpdated.
181 | anyItemUpdated = anyItemUpdated | _updateFunction?.Invoke(existingItem, updateItem) ?? false;
182 | }
183 |
184 | var newItems = collection.Where(item => !Items.Any(contact => _equivalenceComparer.Equals(contact, item))).ToList();
185 |
186 | if (!newItems.Any())
187 | {
188 | return;
189 | }
190 |
191 | foreach (var item in newItems)
192 | {
193 | Items.Add(item);
194 | }
195 |
196 | OnPropertyChanged(new PropertyChangedEventArgs("Count"));
197 | OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, newItems, startIndex));
198 | }
199 | }
200 | }
201 |
--------------------------------------------------------------------------------
/MyContacts/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Resources;
2 | using System.Reflection;
3 | using System.Runtime.CompilerServices;
4 | using System.Runtime.InteropServices;
5 |
6 | // General Information about an assembly is controlled through the following
7 | // set of attributes. Change these attribute values to modify the information
8 | // associated with an assembly.
9 | [assembly: AssemblyTitle("MyContacts")]
10 | [assembly: AssemblyDescription("")]
11 | [assembly: AssemblyConfiguration("")]
12 | [assembly: AssemblyCompany("")]
13 | [assembly: AssemblyProduct("MyContacts")]
14 | [assembly: AssemblyCopyright("Copyright © 2014")]
15 | [assembly: AssemblyTrademark("")]
16 | [assembly: AssemblyCulture("")]
17 | [assembly: NeutralResourcesLanguage("en")]
18 |
19 | // Version information for an assembly consists of the following four values:
20 | //
21 | // Major Version
22 | // Minor Version
23 | // Build Number
24 | // Revision
25 | //
26 | // You can specify all the values or you can default the Build and Revision Numbers
27 | // by using the '*' as shown below:
28 | // [assembly: AssemblyVersion("1.0.*")]
29 | [assembly: AssemblyVersion("1.0.0.0")]
30 | [assembly: AssemblyFileVersion("1.0.0.0")]
31 |
--------------------------------------------------------------------------------
/MyContacts/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # DragAndDropSort
2 | Sortable Drag and Drop Sample
3 |
4 | Drag’n’Drop is just another way the user can interact with the data in a mobile application (quite a powerful one I might add). It can be used to move items in a list from one category to another or simply to adjust the priority of list items. In this context, ListView ordering with drag and drop can be treated as a user input and in the world of MVVM and Xamarin.Forms these changes should be reflected on the ViewModel.
5 |
6 | Android | iOS
7 | --- | ---
8 |  | 
9 |
10 | In this sample, we have a drag and drop reordering functionality for iOS and Android platforms on Xamarin.Forms.
11 |
12 | More information about the implementation can be found at:
13 |
14 | * Android: [Re-Order List View Items with Drag'n'Drop - II](https://canbilgin.wordpress.com/2018/03/17/re-order-listview-items-with-drag-drop-ii/)
15 | * iOS: [Re-Order List View Items with Drag'n'Drop - I](https://canbilgin.wordpress.com/2018/03/04/re-order-listview-items-with-drag-drop-i/)
16 |
--------------------------------------------------------------------------------