@@ -226,17 +226,216 @@ The following code example illustrates how cards numeric property updated using
226226</kanban: SfKanban >
227227
228228{% endhighlight %}
229- {% highlight C# hl_lines="2 6 7 " %}
229+ {% highlight C# hl_lines="1 2 11 12 " %}
230230
231231this.kanban.ItemsSource = new SortingViewModel().Cards;
232232this.kanban.DragEnd += this.OnCardDragEnd;
233233
234234private void OnCardDragEnd(object? sender, KanbanDragEndEventArgs e)
235235{
236+ if (this.kanban == null)
237+ {
238+ return;
239+ }
240+
236241 this.ApplySortingWithoutPositionChange(e);
237242 this.kanban.RefreshKanbanColumn();
238243}
239244
245+ private void ApplySortingWithoutPositionChange(KanbanDragEndEventArgs eventArgs)
246+ {
247+ if (this.kanban == null || eventArgs.Data == null || eventArgs.TargetColumn?.Items == null || eventArgs.SourceColumn == null || (eventArgs.SourceColumn == eventArgs.TargetColumn && eventArgs.SourceIndex == eventArgs.TargetIndex))
248+ {
249+ return;
250+ }
251+
252+ // Retrieve sorting configuration
253+ var sortMappingPath = kanban.SortingMappingPath;
254+ var sortingOrder = kanban.SortingOrder;
255+
256+ // Extract and cast items from the target column
257+ var targetColumnItems = eventArgs.TargetColumn.Items is IList<object> items
258+ ? items.Cast<object>().ToList() : new List<object>();
259+
260+ // Proceed only if sorting path is defined
261+ if (string.IsNullOrEmpty(sortMappingPath))
262+ {
263+ return;
264+ }
265+
266+ // Sort items based on the sorting order
267+ if (targetColumnItems.Count > 0)
268+ {
269+ Func<object, object?> keySelector = item => this.GetPropertyInfo(item.GetType(), sortMappingPath);
270+
271+ targetColumnItems = sortingOrder == KanbanSortingOrder.Ascending
272+ ? targetColumnItems.OrderBy(item => keySelector(item) ?? 0).ToList()
273+ : targetColumnItems.OrderByDescending(item => keySelector(item) ?? 0).ToList();
274+ }
275+
276+ // Determine the index to insert the dragged card.
277+ int currentCardIndex = eventArgs.TargetIndex;
278+ if (currentCardIndex >= 0 && currentCardIndex <= targetColumnItems.Count)
279+ {
280+ targetColumnItems.Insert(currentCardIndex, eventArgs.Data);
281+ }
282+ else
283+ {
284+ targetColumnItems.Add(eventArgs.Data);
285+ currentCardIndex = targetColumnItems.Count - 1;
286+ }
287+
288+ // Update index property of all items using smart positioning logic
289+ this.ApplySmartIndexUpdate(targetColumnItems, sortingOrder, currentCardIndex);
290+ }
291+
292+ private void ApplySmartIndexUpdate(List<object > items, KanbanSortingOrder sortingOrder, int currentCardIndex)
293+ {
294+ if (items == null || items.Count == 0)
295+ {
296+ return;
297+ }
298+
299+ if (sortingOrder == KanbanSortingOrder.Ascending)
300+ {
301+ this.HandleAscendingIndexSorting(items, currentCardIndex);
302+ return;
303+ }
304+
305+ this.HandleDescendingIndexSorting(items, currentCardIndex);
306+ }
307+
308+ private void HandleAscendingIndexSorting(List<object > items, int currentCardIndex)
309+ {
310+ int afterCardIndex = -1;
311+ int lastItemIndex = -1;
312+
313+ // Get the index of the card after the insertion point
314+ if (currentCardIndex < items.Count - 1)
315+ {
316+ var afterCard = items[currentCardIndex + 1];
317+ afterCardIndex = GetCardIndex(afterCard) ?? -1;
318+ }
319+
320+ for (int i = 0; i < items.Count; i++)
321+ {
322+ var item = items[i];
323+ if (item == null)
324+ {
325+ continue;
326+ }
327+
328+ PropertyInfo? propertyInfo = this.GetPropertyInfo(item.GetType(), "Index");
329+ if (propertyInfo == null)
330+ {
331+ continue;
332+ }
333+
334+ int itemIndex = Convert.ToInt32(propertyInfo.GetValue(item) ?? 0);
335+ bool isFirstItem = i == 0;
336+ if (isFirstItem)
337+ {
338+ // If the inserted card is at the beginning, assign a smart index
339+ if (currentCardIndex == 0)
340+ {
341+ lastItemIndex = afterCardIndex > 1 ? afterCardIndex - 1 : 1;
342+ propertyInfo.SetValue(item, lastItemIndex);
343+ }
344+ else
345+ {
346+ lastItemIndex = itemIndex;
347+ }
348+ }
349+ else
350+ {
351+ // Increment index for subsequent items
352+ lastItemIndex++;
353+ propertyInfo.SetValue(item, lastItemIndex);
354+ }
355+ }
356+ }
357+
358+ private void HandleDescendingIndexSorting(List<object > items, int currentCardIndex)
359+ {
360+ int beforeCardIndex = -1;
361+ int lastItemIndex = -1;
362+
363+ // Get the index of the card before the insertion point
364+ if (currentCardIndex > 0 && currentCardIndex < items.Count)
365+ {
366+ var cardBefore = items[currentCardIndex - 1];
367+ beforeCardIndex = GetCardIndex(cardBefore) ?? -1;
368+ }
369+
370+ for (int i = items.Count - 1; i >= 0; i--)
371+ {
372+ var item = items[i];
373+ if (item == null)
374+ {
375+ continue;
376+ }
377+
378+ PropertyInfo? propertyInfo = this.GetPropertyInfo(item.GetType(), "Index");
379+ if (propertyInfo == null)
380+ {
381+ continue;
382+ }
383+
384+ int itemIndex = Convert.ToInt32(propertyInfo.GetValue(item) ?? 0);
385+ bool isLastItem = i == items.Count - 1;
386+ if (isLastItem)
387+ {
388+ // If the inserted card is at the end, assign a smart index
389+ if (currentCardIndex == items.Count - 1)
390+ {
391+ lastItemIndex = beforeCardIndex > 1 ? beforeCardIndex - 1 : 1;
392+ propertyInfo.SetValue(item, lastItemIndex);
393+ }
394+ else
395+ {
396+ lastItemIndex = itemIndex;
397+ }
398+ }
399+ else
400+ {
401+ lastItemIndex++;
402+ propertyInfo.SetValue(item, lastItemIndex);
403+ }
404+ }
405+ }
406+
407+ private int? GetCardIndex(object cardDetails)
408+ {
409+ if (cardDetails == null)
410+ {
411+ return null;
412+ }
413+
414+ PropertyInfo? propertyInfo = this.GetPropertyInfo(cardDetails.GetType(), "Index");
415+ if (propertyInfo == null)
416+ {
417+ return null;
418+ }
419+
420+ var indexValue = propertyInfo.GetValue(cardDetails);
421+ if (indexValue != null)
422+ {
423+ return Convert.ToInt32(indexValue);
424+ }
425+
426+ return null;
427+ }
428+
429+ private PropertyInfo? GetPropertyInfo(Type type, string key)
430+ {
431+ return this.GetPropertyInfoCustomType(type, key);
432+ }
433+
434+ private PropertyInfo? GetPropertyInfoCustomType([ DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] Type type, string key)
435+ {
436+ return type.GetProperty(key);
437+ }
438+
240439{% endhighlight %}
241440{% highlight c# tabtitle="CardDetails.cs" %}
242441
0 commit comments