Wpf 如何使ItemsSource类型变得无知?

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

我正在为WPF DatagGrid开发一个拖放机制。到目前为止,我的工作如下:

 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.ObservableCollection
1[drag.Section]”的对象强制转换为“type”System.Collections.generic.List
1[System.object]“。属性的类型为
IEnumerable
,因此您可以强制转换为该类型,但无法向其中添加任何项。那么这里的类型约束是什么?您如何知道
ItemsSource
当前设置为
IList
或其他类型的列表?
var sourceIndex = Dg.ItemsSource.Cast<object>().ToList().IndexOf(item);