gpt4 book ai didi

c# - Gong Solutions 拖放排序列表从列表中删除项目

转载 作者:行者123 更新时间:2023-11-30 22:57:03 25 4
gpt4 key购买 nike

我正在尝试拖放我的 Gong Solutions 以对单个列表进行排序。当我拖放一个项目时,它会从列表中删除该项目,我可以看到它从界面上消失了。看来 DragOver 方法没有先移动对象,所以当 Drop 方法触发时,它只是删除了项目。

当我删除属性 dd:DragDrop.DropHandler="{Binding}" 时,界面上的拖放操作正常。但是,我必须触发事件,这样我才能知道列表何时被重新排序。

XAML:

<Window x:Class="Reorder_item_WPF.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:dd="clr-namespace:GongSolutions.Wpf.DragDrop;assembly=GongSolutions.Wpf.DragDrop">
<Grid>
<ListBox Grid.Column="1" SelectionMode="Extended" ItemsSource="{Binding MSPCollection}"
dd:DragDrop.IsDragSource="True" Width="300" Margin="0,0,5,0"
dd:DragDrop.IsDropTarget="True"
dd:DragDrop.DropHandler="{Binding}">

<ListBox.ItemTemplate>
<DataTemplate>
<Grid Background="#2ba3d5" Height="50" Width="280">
<TextBlock Drop="TextBlock_Drop" Text="{Binding Name}"
Foreground="White"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="40"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Window>

C#:

public class MSP {
public int Id { get; set; }
public string Name { get; set; }
}

class MainViewModel : IDropTarget
{
public ObservableCollection<MSP> MSPCollection { get; set; }

public MainViewModel() {
MSPCollection = new ObservableCollection<MSP>();

MSPCollection.Add(new MSP() {
Id = 1,
Name = "Anis Derbel"
});

MSPCollection.Add(new MSP()
{
Id = 2,
Name = "Firas Mdimagh"
});

MSPCollection.Add(new MSP()
{
Id = 3,
Name = "Khaled Jemni"
});

MSPCollection.Add(new MSP()
{
Id = 4,
Name = "Sahbouch"
});
}

public void DragOver(IDropInfo dropInfo) {
if (dropInfo.Data is MSP) {
dropInfo.DropTargetAdorner = DropTargetAdorners.Highlight;
dropInfo.Effects = DragDropEffects.Move;
}
}

public void Drop(IDropInfo dropInfo) {
MSP msp = (MSP)dropInfo.Data;
((IList)dropInfo.DragInfo.SourceCollection).Remove(msp);
}
}

最佳答案

DragOver 不会删除任何项目。您正在使用 Drop 方法删除项目。您不应该在 DragOver 方法中进行任何删除或添加,这就是 Drop 方法的用途。 DragOver 应该只用于设置目标装饰器和效果。我使用 ILSpy 查看他们的代码(见下文),这有助于阐明这里发生的事情。他们有一个名为 DefaultDropHandler : IDropTarget 的类,顾名思义,如果未使用附加属性 dd:DragDrop.DropHandler 分配,则该类是默认的放置处理程序。因此,当您删除 dd:DragDrop.DropHandler="{Binding}" 行时,这就是用于放置操作的内容。查看他们的代码,一切都为您处理,即添加和删除项目,并在此过程中进行大量错误检查和索引控制。

当您确实将放置处理程序设置为您的 ViewModel 时,默认处理程序中的任何代码都不会执行,因为您将该处理程序替换为您的 ViewModel。因此,您必须完全处理跌落。换句话说,你必须做所有的错误和类型检查,删除项目和添加项目(如果你有多个列表),并保持正确的顺序。在执行任何删除和添加之前,您可能还想检查源集合是否与目标集合不同,但这仍然不会将它们添加到正确的位置。

因为您只有一个列表,所以不要在 Drop 方法中删除该项目。但是,由于我上面提到的原因,什么都不会发生。如果您确实有多个列表,可以按照以下方法将项目从一个列表移动到另一个列表:

public void Drop(IDropInfo dropInfo) 
{
MSP msp = (MSP)dropInfo.Data;
if(dropInfo.DragInfo.SourceCollection != dropInfo.TargetCollection)
{
((IList)dropInfo.DragInfo.SourceCollection).Remove(msp);
((IList)dropInfo.TargetCollection).Add(msp);
}
}

如果您需要的话,您必须按照正确的顺序排列元素。作为完成所有这些工作的替代方法,您可以利用和扩展它们的默认处理程序。他们制作了 Drop 方法 virtual,因此您可以让您的 View 模型继承自 DefaultDropHandler
(即 class MainViewModel : DefaultDropHandler)而不是实现 IDropTarget 接口(interface)。然后,简单地覆盖 Drop 方法,并调用基本方法。像这样:

public override void Drop(IDropInfo dropInfo)
{
base.Drop(dropInfo);
//do other stuff
}

如果需要,您也可以用相同的方式重写 DragOver 方法,但如果不需要,它将只使用默认行为。

额外信息

如果你很好奇,下面是 Gong 在你没有分配时使用的默认处理程序:

public virtual void Drop(IDropInfo dropInfo)
{
if (dropInfo != null && dropInfo.DragInfo != null)
{
int insertIndex = (dropInfo.InsertIndex != dropInfo.UnfilteredInsertIndex) ? dropInfo.UnfilteredInsertIndex : dropInfo.InsertIndex;
ItemsControl itemsControl = dropInfo.VisualTarget as ItemsControl;
if (itemsControl != null)
{
IEditableCollectionView editableItems = itemsControl.Items;
if (editableItems != null)
{
NewItemPlaceholderPosition newItemPlaceholderPosition = editableItems.NewItemPlaceholderPosition;
if (newItemPlaceholderPosition == NewItemPlaceholderPosition.AtBeginning && insertIndex == 0)
{
insertIndex++;
}
else if (newItemPlaceholderPosition == NewItemPlaceholderPosition.AtEnd && insertIndex == itemsControl.Items.Count)
{
insertIndex--;
}
}
}
IList destinationList = dropInfo.TargetCollection.TryGetList();
List<object> data = ExtractData(dropInfo.Data).OfType<object>().ToList();
List<object>.Enumerator enumerator;
if (!ShouldCopyData(dropInfo))
{
IList sourceList = dropInfo.DragInfo.SourceCollection.TryGetList();
if (sourceList != null)
{
enumerator = data.GetEnumerator();
try
{
while (enumerator.MoveNext())
{
object o2 = enumerator.Current;
int index = sourceList.IndexOf(o2);
if (index != -1)
{
sourceList.RemoveAt(index);
if (destinationList != null && object.Equals(sourceList, destinationList) && index < insertIndex)
{
insertIndex--;
}
}
}
}
finally
{
((IDisposable)enumerator).Dispose();
}
}
}
if (destinationList != null)
{
TabControl tabControl = dropInfo.VisualTarget as TabControl;
bool cloneData = dropInfo.Effects.HasFlag(DragDropEffects.Copy) || dropInfo.Effects.HasFlag(DragDropEffects.Link);
enumerator = data.GetEnumerator();
try
{
while (enumerator.MoveNext())
{
object o = enumerator.Current;
object obj2Insert = o;
if (cloneData)
{
ICloneable cloneable = o as ICloneable;
if (cloneable != null)
{
obj2Insert = cloneable.Clone();
}
}
destinationList.Insert(insertIndex++, obj2Insert);
if (tabControl != null)
{
TabItem obj = tabControl.ItemContainerGenerator.ContainerFromItem(obj2Insert) as TabItem;
if (obj != null)
{
obj.ApplyTemplate();
}
tabControl.SetSelectedItem(obj2Insert);
}
}
}
finally
{
((IDisposable)enumerator).Dispose();
}
}
}
}

关于c# - Gong Solutions 拖放排序列表从列表中删除项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53877125/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com