如何使ItemsSource类型不知道?

时间:2018-07-14 21:34:43

标签: 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 = 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;
    }

部分是数据网格的ItemsSource。

我想使此代码忽略类型,因此我可以将其用于Section以外的其他类型。

这行不通:

var sourceIndex = (int) ((List<object>) Dg.ItemsSource).FindIndex(a => a == item);

会怎样?

1 个答案:

答案 0 :(得分:1)

您不能将集合投射到List中。方便的IEnumerable有一个Cast<T>方法,该方法返回一个IEnumerable<T>集合。并且更方便地从IEnumerable<T>对象访问 linq 方法。

using System.Linq;

因此,为了使它变得无类型,可以将每个元素都转换为object类型。

object test = Dg.ItemsSource.Cast<object>().First(a => a == item);

但是只有List具有IndexOf方法,因此调用ToList使我们能够找到项目的索引:

var sourceIndex = Dg.ItemsSource.Cast<object>().ToList().IndexOf(item);