@@ -240,15 +240,231 @@ The following code example illustrates how cards numeric property updated using
240240</kanban: SfKanban >
241241
242242{% endhighlight %}
243- {% highlight C# hl_lines="2 6 7" %}
243+ {% highlight C# hl_lines="5 6 7 11 22 23 " %}
244244
245+ private KanbanCardItem selectedCard;
246+ private KanbanColumn? targetColumn;
247+
248+ // Add the following lines in constructor
245249this.kanban.ItemsSource = new SortingViewModel().Cards;
250+ this.kanban.CardDragStart += OnKanbanCardDragStart;
246251this.kanban.CardDragEnd += OnKanbanCardDragEnd;
247252
253+ private void OnKanbanCardDragStart(object sender, KanbanDragStartEventArgs e)
254+ {
255+ this.selectedCard = e.SelectedCard;
256+ }
257+
248258private void OnKanbanCardDragEnd(object sender, KanbanDragEndEventArgs e)
249259{
260+ if (this.kanban == null || this.selectedCard == null || e.TargetColumn == null)
261+ {
262+ return;
263+ }
264+
250265 this.ApplySortingWithoutPositionChange(e);
251- this.kanban.RefreshKanbanColumn(e.TargetKey.ToString());
266+ this.kanban.RefreshKanbanColumn(e.TargetKey.ToString());
267+ }
268+
269+ private void ApplySortingWithoutPositionChange(KanbanDragEndEventArgs e)
270+ {
271+ var cardItems = e.TargetColumn.Items.Cast<KanbanCardItem >().ToList();
272+ if (this.kanban == null || this.selectedCard == null || this.selectedCard.Content == null || e.TargetColumn == null || e.TargetKey == null || cardItems == null || !cardItems.Any()
273+ || e.SelectedColumn == null || (e.SelectedColumn == e.TargetColumn && e.SelectedColumnIndex == e.TargetCardIndex))
274+ {
275+ return;
276+ }
277+
278+ // Retrieve sorting configuration
279+ var sortMappingPath = this.kanban.SortingMappingPath;
280+ var sortingOrder = this.kanban.SortingOrder;
281+ CardDetails cardDetails = this.selectedCard.Content as CardDetails;
282+
283+ // Proceed only if sorting path is defined
284+ if (cardDetails == null || string.IsNullOrEmpty(sortMappingPath))
285+ {
286+ return;
287+ }
288+
289+ // Extract items from the target colum
290+ var targetColumnItems = cardItems.Where(card => card != null && card.Content is CardDetails).ToList();
291+
292+ // Sort items based on the sorting order
293+ if (targetColumnItems.Count > 0)
294+ {
295+ Func<KanbanCardItem, object> keySelector = item => this.GetPropertyInfo(item.GetType(), sortMappingPath);
296+ targetColumnItems = sortingOrder == KanbanSortingOrder.Ascending
297+ ? targetColumnItems.OrderBy(item => keySelector(item) ?? 0).ToList()
298+ : targetColumnItems.OrderByDescending(item => keySelector(item) ?? 0).ToList();
299+ }
300+
301+ // Determine the index to insert the dragged card.
302+ int currentCardIndex = e.TargetCardIndex;
303+
304+ if (e.SelectedColumn != e.TargetColumn)
305+ {
306+ cardDetails.Category = e.TargetKey.ToString();
307+ }
308+
309+ if (currentCardIndex >= 0 && currentCardIndex <= targetColumnItems.Count)
310+ {
311+ targetColumnItems.Insert(currentCardIndex, this.selectedCard);
312+ }
313+ else
314+ {
315+ targetColumnItems.Add(this.selectedCard);
316+ currentCardIndex = targetColumnItems.Count - 1;
317+ }
318+
319+ // Update index property of all items using smart positioning logic
320+ this.ApplySmartIndexUpdate(targetColumnItems, currentCardIndex);
321+ }
322+
323+ private void ApplySmartIndexUpdate(List<KanbanCardItem > items, int droppedIndex)
324+ {
325+ if (this.kanban == null || items == null || items.Count == 0)
326+ {
327+ return;
328+ }
329+
330+ if (this.kanban.SortingOrder == KanbanSortingOrder.Ascending)
331+ {
332+ this.HandleAscendingIndexSorting(items, droppedIndex);
333+ return;
334+ }
335+
336+ this.HandleDescendingIndexSorting(items, droppedIndex);
337+ }
338+
339+ private void HandleAscendingIndexSorting(List<KanbanCardItem > items, int currentCardIndex)
340+ {
341+ int afterCardIndex = -1;
342+ int lastItemIndex = -1;
343+
344+ // Get the index of the card after the insertion point
345+ if (currentCardIndex < items.Count - 1)
346+ {
347+ var afterCard = items[currentCardIndex + 1];
348+ afterCardIndex = GetCardIndex(afterCard?.Content) ?? -1;
349+ }
350+
351+ for (int i = 0; i < items.Count; i++)
352+ {
353+ var item = items[i].Content;
354+ if (item == null)
355+ {
356+ continue;
357+ }
358+
359+ PropertyInfo propertyInfo = this.GetPropertyInfo(item.GetType(), "Index");
360+ if (propertyInfo == null)
361+ {
362+ continue;
363+ }
364+
365+ int itemIndex = Convert.ToInt32(propertyInfo.GetValue(item) ?? 0);
366+ bool isFirstItem = i == 0;
367+ if (isFirstItem)
368+ {
369+ // If the inserted card is at the beginning, assign a smart index
370+ if (currentCardIndex == 0)
371+ {
372+ lastItemIndex = afterCardIndex > 1 ? afterCardIndex - 1 : 1;
373+ propertyInfo.SetValue(item, lastItemIndex);
374+ }
375+ else
376+ {
377+ lastItemIndex = itemIndex;
378+ }
379+ }
380+ else
381+ {
382+ // Increment index for subsequent items
383+ lastItemIndex++;
384+ propertyInfo.SetValue(item, lastItemIndex);
385+ }
386+ }
387+ }
388+
389+ private void HandleDescendingIndexSorting(List<KanbanCardItem > items, int currentCardIndex)
390+ {
391+ int beforeCardIndex = -1;
392+ int lastItemIndex = -1;
393+
394+ // Get the index of the card before the insertion point
395+ if (currentCardIndex > 0 && currentCardIndex < items.Count)
396+ {
397+ var cardBefore = items[currentCardIndex - 1];
398+ beforeCardIndex = GetCardIndex(cardBefore?.Content) ?? -1;
399+ }
400+
401+ for (int i = items.Count - 1; i >= 0; i--)
402+ {
403+ var item = items[i].Content;
404+ if (item == null)
405+ {
406+ continue;
407+ }
408+
409+ PropertyInfo propertyInfo = this.GetPropertyInfo(item.GetType(), "Index");
410+ if (propertyInfo == null)
411+ {
412+ continue;
413+ }
414+
415+ int itemIndex = Convert.ToInt32(propertyInfo.GetValue(item) ?? 0);
416+ bool isLastItem = i == items.Count - 1;
417+ if (isLastItem)
418+ {
419+ // If the inserted card is at the end, assign a smart index
420+ if (currentCardIndex == items.Count - 1)
421+ {
422+ lastItemIndex = beforeCardIndex > 1 ? beforeCardIndex - 1 : 1;
423+ propertyInfo.SetValue(item, lastItemIndex);
424+ }
425+ else
426+ {
427+ lastItemIndex = itemIndex;
428+ }
429+ }
430+ else
431+ {
432+ lastItemIndex++;
433+ propertyInfo.SetValue(item, lastItemIndex);
434+ }
435+ }
436+ }
437+
438+ private int? GetCardIndex(object cardDetails)
439+ {
440+ if (cardDetails == null)
441+ {
442+ return null;
443+ }
444+
445+ PropertyInfo propertyInfo = this.GetPropertyInfo(cardDetails.GetType(), "Index");
446+ if (propertyInfo == null)
447+ {
448+ return null;
449+ }
450+
451+ var indexValue = propertyInfo.GetValue(cardDetails);
452+ if (indexValue != null)
453+ {
454+ return Convert.ToInt32(indexValue);
455+ }
456+
457+ return null;
458+ }
459+
460+ private PropertyInfo GetPropertyInfo(Type type, string key)
461+ {
462+ return this.GetPropertyInfoCustomType(type, key);
463+ }
464+
465+ private PropertyInfo GetPropertyInfoCustomType(Type type, string key)
466+ {
467+ return type.GetProperty(key);
252468}
253469
254470{% endhighlight %}
0 commit comments