WiiMaxx
WiiMaxx

Reputation: 5420

How to Drag Drop DatagridCellContent

Hi does anybody know how to drag and drop the Content of a DataGridCell in a MVVM friendly way?

I saw examples for ListBox's but i'm not able to implement this for a DataGrid.

in case the way how i create my Columns is impotent i added an example below:

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);
            }
        }
    }
}

ViewModel

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);
            }
        }
    }
}

Upvotes: 1

Views: 3119

Answers (2)

Karl_Schuhmann
Karl_Schuhmann

Reputation: 1332

Look this link. In the CustomWPFControl.DragDrop file, there is a solution which should work.

In XAML you need to add this to your control:

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

If you set a DragTemplate, the item you move will follow the mouse.

Upvotes: 1

Matt
Matt

Reputation: 2682

There are a few good samples out there that may help you on your way, such as MVVM and the WPF DataGrid w/ demo app.

You may also want to take a look at this SO question that has several links to implementing drag-drop in the grid.

Upvotes: 0

Related Questions