Wpf 如何使ItemsSource类型变得无知?
我正在为WPF DatagGrid开发一个拖放机制。到目前为止,我的工作如下:Wpf 如何使ItemsSource类型变得无知?,wpf,datagrid,drag-and-drop,Wpf,Datagrid,Drag And Drop,我正在为WPF DatagGrid开发一个拖放机制。到目前为止,我的工作如下: protected override void OnMouseMove(MouseEventArgs e) { base.OnMouseMove(e); if (e.LeftButton == MouseButtonState.Pressed && Sections.Count > 1) { var row = U
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
if (e.LeftButton == MouseButtonState.Pressed && Sections.Count > 1)
{
var row = UIHelpers.TryFindFromPoint<DataGridRow>(Dg, e.GetPosition(Dg));
var item = row.Item;
var sourceIndex = Sections.IndexOf((Section) item);
// Package the data.
DataObject data = new DataObject();
data.SetData(typeof(int),sourceIndex);
// Inititate the drag-and-drop operation.
DragDrop.DoDragDrop(this, data, DragDropEffects.Move);
}
}
protected override void OnDrop( DragEventArgs e)
{
base.OnDrop(e);
e.Effects = DragDropEffects.Move;
if (e.Data.GetDataPresent(typeof(int)))
{
var row = UIHelpers.TryFindFromPoint<DataGridRow>(Dg, e.GetPosition(Dg));
if (row == null)
return;
var item = row.Item;
var targetIndex = Sections.IndexOf((Section) item);
var sourceIndex = (int) e.Data.GetData(typeof(int));
if (sourceIndex != targetIndex)
{
var list = (IList<Section>)Dg.ItemsSource;
if (targetIndex == -1)
{
list.Add(list[sourceIndex]);
list.RemoveAt(sourceIndex);
}
else
{
list.Insert(targetIndex, list[sourceIndex]);
if (sourceIndex < targetIndex)
list.RemoveAt(sourceIndex);
else
list.RemoveAt(sourceIndex + 1);
}
}
}
e.Handled = true;
}
mouseMove上的受保护覆盖无效(MouseEventArgs e)
{
基地移动(e);
如果(e.LeftButton==MouseButtonState.Pressed&&Sections.Count>1)
{
var row=UIHelpers.TryFindFromPoint(Dg,e.GetPosition(Dg));
var项目=行项目;
var sourceIndex=Sections.IndexOf((Section)项);
//打包数据。
数据对象数据=新的数据对象();
SetData(typeof(int),sourceIndex);
//初始化拖放操作。
DragDrop.DoDragDrop(this、data、DragDropEffects.Move);
}
}
受保护的覆盖无效OnDrop(DragEventArgs e)
{
基地.昂德罗普(e);
e、 效果=DragDropEffects.Move;
if(例如Data.GetDataPresent(typeof(int)))
{
var row=UIHelpers.TryFindFromPoint(Dg,e.GetPosition(Dg));
if(行==null)
返回;
var项目=行项目;
var targetIndex=节.索引((节)项);
var sourceIndex=(int)e.Data.GetData(typeof(int));
if(sourceIndex!=targetIndex)
{
var list=(IList)Dg.ItemsSource;
如果(targetIndex==-1)
{
list.Add(list[sourceIndex]);
list.RemoveAt(sourceIndex);
}
其他的
{
插入(targetIndex,list[sourceIndex]);
if(sourceIndex
节是DataGrid的ItemsSource
我想让这个代码类型变得无知,这样我就可以将它用于除Section之外的其他类型
这行不通:
var sourceIndex = (int) ((List<object>) Dg.ItemsSource).FindIndex(a => a == item);
var sourceIndex=(int)((List)Dg.ItemsSource.FindIndex(a=>a==item);
怎么办?您不能将集合强制转换到
列表中。方便地IEnumerable
有一个Cast
方法,该方法返回一个IEnumerable
集合。更方便的是,可以从IEnumerable
对象访问linq方法
using System.Linq;
因此,为了使其类型不受影响,您可以将每个元素强制转换为对象
类型
object test = Dg.ItemsSource.Cast<object>().First(a => a == item);
为什么最后一点不起作用?这里的问题是您的Sections变量,您认为如何根据泛型类型匹配好的集合?我得到的消息是:无法将类型为“System.Collections.ObjectModel.ObservableCollection1[drag.Section]”的对象强制转换为“type”System.Collections.generic.List
1[System.object]“。属性的类型为IEnumerable
,因此您可以强制转换为该类型,但无法向其中添加任何项。那么这里的类型约束是什么?您如何知道ItemsSource
当前设置为IList
或其他类型的列表?
var sourceIndex = Dg.ItemsSource.Cast<object>().ToList().IndexOf(item);