如何拖放数据网格单元格内容

时间:2014-01-10 16:39:21

标签: wpf mvvm datagrid drag-and-drop

您是否有人知道如何以MVVM友好的方式拖放DataGridCell的内容?

我看到了ListBox的示例,但我无法为DataGrid实现此功能。

如果我创建我的列的方式无能为力,我在下面添加了一个示例:

XAML

<Window x:Class="ListToDatagrid.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:ListToDatagrid"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <local:VM/>
    </Window.DataContext>
    <StackPanel>
        <TextBox Text="{Binding Text}"/>
        <DataGrid ItemsSource="{Binding MySource}"
                  local:ColumnsBehavior.MyColumns="{Binding Columns}"
                  AutoGenerateColumns="False"
                  SelectionMode="Single" SelectionUnit="Cell"/>
    </StackPanel>
</Window>

AutoGeneratingColumnEventToCommandBehaviour

using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace ListToDatagrid
{
    public class AutoGeneratingColumnEventToCommandBehaviour
    {
        public static readonly DependencyProperty CommandProperty =
            DependencyProperty.RegisterAttached(
                "Command",
                typeof(ICommand),
                typeof(AutoGeneratingColumnEventToCommandBehaviour),
                new PropertyMetadata(
                    null,
                    CommandPropertyChanged));

        public static void SetCommand(DependencyObject o, ICommand value)
        {
            o.SetValue(CommandProperty, value);
        }

        public static ICommand GetCommand(DependencyObject o)
        {
            return o.GetValue(CommandProperty) as ICommand;
        }

        private static void CommandPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var dataGrid = d as DataGrid;
            if (dataGrid != null)
            {
                if (e.OldValue != null)
                    dataGrid.AutoGeneratingColumn -= OnAutoGeneratingColumn;

                if (e.NewValue != null)
                    dataGrid.AutoGeneratingColumn += OnAutoGeneratingColumn;
            }
        }

        private static void OnAutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
        {
            var dependencyObject = sender as DependencyObject;
            if (dependencyObject != null)
            {
                var command = dependencyObject.GetValue(CommandProperty) as ICommand;
                if (command != null && command.CanExecute(e))
                    command.Execute(e);
            }
        }
    }
}

视图模型

using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using Framework;

namespace ListToDatagrid
{
    public class VM : VMBase
    {
        #region Feld Member

        private ObservableCollection<DataGridColumn> columns;
        private ObservableCollection<object[]> mySource;
        private string text = "default";

        #endregion Feld Member

        #region Properties

        public ObservableCollection<object[]> MySource
        {
            get { return mySource; }
            set { mySource = value; }
        }

        public string Text
        {
            get { return text; }
            set { text = value; }
        }

        public ObservableCollection<DataGridColumn> Columns
        {
            get
            {
                if (columns == null)
                    columns = createColumns();
                return columns;
            }
            set { columns = value; }
        }

        #endregion Properties

        #region Column create Methods

        private ObservableCollection<DataGridColumn> createColumns()
        {
            var temp = new ObservableCollection<DataGridColumn>();
            var DTemplate = createDataTemplate();

            for (int i = 0; i < 5; i++)
            {
                DataGridTemplateColumn templateColumn = new DataGridTemplateColumn();

                templateColumn.Header = "test" + i;
                templateColumn.CellTemplate = DataTemplatePresenter(DTemplate, i);
                //templateColumn.CellEditingTemplate=...

                temp.Add(templateColumn);
            }

            return temp;
        }

        private DataTemplate DataTemplatePresenter(DataTemplate dtemp, int i)
        {
            var FEFactory = new FrameworkElementFactory(typeof(ContentPresenter));
            FEFactory.SetBinding(ContentPresenter.ContentProperty, new Binding(string.Format("[{0}]", i.ToString())));
            FEFactory.SetBinding(ContentPresenter.DataContextProperty, new Binding(string.Format("[{0}]", i.ToString())));
            FEFactory.SetValue(ContentPresenter.ContentTemplateProperty, dtemp);

            return new DataTemplate { VisualTree = FEFactory };
        }

        private DataTemplate createDataTemplate()
        {
            //create the data template
            DataTemplate cardLayout = new DataTemplate();
            cardLayout.DataType = typeof(string);

            //set up the card holder textblock
            FrameworkElementFactory cardHolder = new FrameworkElementFactory(typeof(TextBlock));
            cardHolder.SetBinding(TextBlock.TextProperty, new Binding(""));

            //set the visual tree of the data template
            cardLayout.VisualTree = cardHolder;
            return cardLayout;
        }

        #endregion Column create Methods

        public VM()
        {
            mySource = new ObservableCollection<object[]>();
            for (int i = 0; i < 3; i++)
            {
                var myObject = new object[5];
                myObject[0] = "Cell1";
                myObject[1] = "Cell2";
                myObject[2] = "Cell3";
                myObject[3] = "Cell4";
                myObject[4] = "Cell5";

                mySource.Add(myObject);
            }
        }
    }
}

2 个答案:

答案 0 :(得分:1)

this link。在CustomWPFControl.DragDrop文件中,有一个应该有效的解决方案。

在XAML中,您需要将其添加到您的控件中:

DragDrop:DragDropHelper.IsDropTarget="True"  
DragDrop:DragDropHelper.IsDragSource="True" 
DragDrop:DragDropHelper.DragDropTemplate="{StaticResource DragTemplate}"

如果设置了DragTemplate,则移动的项目将遵循鼠标。

答案 1 :(得分:0)

有一些好的样本可以帮助您,例如MVVM and the WPF DataGrid w/ demo app

您可能还想查看this SO question,其中包含多个指向在网格中实施拖放的链接。