C# 通过拖放对列表进行排序,可以从列表中删除项目
我试图让我的解决方案拖放到一个单一的列表排序。当我拖放一个项目时,它会从列表中删除该项目,我可以看到它从界面中消失。似乎C# 通过拖放对列表进行排序,可以从列表中删除项目,c#,wpf,xaml,drag-and-drop,C#,Wpf,Xaml,Drag And Drop,我试图让我的解决方案拖放到一个单一的列表排序。当我拖放一个项目时,它会从列表中删除该项目,我可以看到它从界面中消失。似乎DragOver方法没有首先移动对象,因此当Drop方法触发时,它只是删除该项 当我删除属性dd:DragDrop.DropHandler=“{Binding}”时,界面上的拖放工作正常。但是,我必须有一个事件火灾,以便我知道列表何时被重新排序 XAML: <Window x:Class="Reorder_item_WPF.MainWindow" xmln
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>
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);
}
}
C#:
<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>
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);
}
}
公共类MSP{
公共int Id{get;set;}
公共字符串名称{get;set;}
}
类MainViewModel:IDropTarget
{
公共ObservableCollection MSPCollection{get;set;}
公共主视图模型(){
MSPCollection=新的ObservableCollection();
添加(新的MSP(){
Id=1,
Name=“Anis Derbel”
});
添加(新的MSP()
{
Id=2,
Name=“Firas Mdimagh”
});
添加(新的MSP()
{
Id=3,
Name=“Khaled Jemni”
});
添加(新的MSP()
{
Id=4,
Name=“Sahbouch”
});
}
公共无效DragOver(IDropInfo dropInfo){
如果(dropInfo.Data是MSP){
dropInfo.DropTargetAdorner=DropTargetAdorner.Highlight;
dropInfo.Effects=DragDropEffects.Move;
}
}
公共作废删除(IDropInfo dropInfo){
MSP MSP=(MSP)dropInfo.Data;
((IList)dropInfo.DragInfo.SourceCollection).Remove(msp);
}
}
DragOver
不会删除任何项目。您正在删除Drop
方法中的项。您不应该在DragOver
方法中进行任何删除或添加操作,这就是Drop
方法的作用DragOver
只能用于设置目标装饰器和效果。我使用ILSpy查看了他们的代码(见下文),这有助于了解这里发生了什么。它们有一个名为DefaultDropHandler:IDropTarget
的类,顾名思义,如果没有使用附加属性dd:DragDrop.DropHandler
指定一个类,则该类是默认的DropHandler。因此,当您删除行dd:DragDrop.DropHandler=“{Binding}”
时,这就是用于drop操作的内容。看看他们的代码,一切都是为你自己处理的,也就是说,项目被添加和删除,整个过程中有大量的错误检查和索引控制
当您确实将drop处理程序设置为您的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
,因此您可以使视图模型继承自DefaultDropHandler
(即
class MainViewModel:DefaultDropHandler
)而不是实现IDROPTTarget
接口。然后,只需重写Drop
方法,并调用base方法。大概是这样的:
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();
}
}
}
}
公共虚拟作废删除(IDropInfo dropInfo)
{
if(dropInfo!=null&&dropInfo.DragInfo!=null)
{
int insertIndex=(dropInfo.insertIndex!=dropInfo.UnfilteredInsertIndex)?dropInfo.UnfilteredInsertIndex:dropInfo.insertIndex;
ItemsControl ItemsControl=dropInfo.VisualTarget作为ItemsControl;
if(itemsControl!=null)
{
IEditableCollectionView editableItems=itemsControl.Items;
if(可编辑项!=null)
{
NewItemPlaceholder位置NewItemPlaceholder位置=editableItems.NewItemPlaceholder位置;
if(newItemPlaceholderPosition==newItemPlaceholderPosition.atStart&&insertIndex==0)
{
insertIndex++;
}
else if(newItemPlaceholderPosition==newItemPlaceholderPosition.AtEnd&&insertIndex==itemsControl.Items.Count)
{
插入索引--;
}
}
}
IList destinationList=dropInfo.TargetCollection.TryGetList();
List data=ExtractData(dropInfo.data).OfType().ToList();
列表.枚举器枚举器;
如果(!ShouldCopyData(dropInfo))
{
IList sourceList=dropInfo.DragInfo.SourceCollection.TryGetList();
if(sourceList!=null)
{
枚举数