简体   繁体   中英

Translate DataGrid MouseEvent so I do not have code in View's Code-Behind

I have a working code with a Datagrid as the main control. I used a Datagrid as it is very easy to bind data into it.

My code requires moving cells into other columns so I always need to check which cell I am on when the mouse is clicked, as well as when it is released.

My current implementation is working as expected. However, the way I check for the row and cell is through the VIEW's code-behind. My project leader is looking for an alternative to have this done thru binding as he wants to keep the VIEW's code-behind as clean as possible. I have tried all I could but I can't find properties which would give me both the cells column and row index.

Please see the code below. (Omitted some of the columns as it would exceed the limit.)

the XAML :

<UserControl x:Class="Widget5.View.WorkItemsDisplay"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:converter="clr-namespace:Widget5.Converter"             
             mc:Ignorable="d" 
             d:DesignHeight="630" Width="690" Padding="0" Margin="0">

    <UserControl.Resources>
        <converter:RowNumberConverter x:Key="rowNumberConverter" />
        <converter:HourSlotToBrushConverter x:Key="hourSlotColorConverter" />

    </UserControl.Resources>

    <Grid Margin="0" Width="690" HorizontalAlignment="Left" MouseRightButtonUp="Grid_MouseRightButtonUp" MouseUp="Grid_MouseUp">
        <Grid.RowDefinitions>
            <RowDefinition Height="24"></RowDefinition>
            <RowDefinition></RowDefinition>
            <!--<RowDefinition Height="30"></RowDefinition>-->
        </Grid.RowDefinitions>

        <!--<Grid HorizontalAlignment="Left" Height="24" VerticalAlignment="Bottom" Grid.Row="2"
              Width="680">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="5" />
                <ColumnDefinition Width="50" />
                <ColumnDefinition Width="2" />
                <ColumnDefinition Width="50" />
                <ColumnDefinition Width="2" />
                <ColumnDefinition Width="50" />
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="50" />
                <ColumnDefinition Width="10" />
            </Grid.ColumnDefinitions>
            <Button Grid.Column="1" Width="48"
                    Command="{Binding AddCommand}">Add</Button>
            <Button Grid.Column="3" Width="48"
                    Command="{Binding DeleteCommand}">Delete</Button>
            <Button Grid.Column="5" Width="48"
                    Command="{Binding SaveCommand}">Save</Button>
            <Button Grid.Column="7" Width="48"
                    Command="{Binding RefreshCommand}">Refresh</Button>
        </Grid>-->

        <Grid HorizontalAlignment="Left" Height="24" VerticalAlignment="Top" Width="690" Grid.Row="0"
              Background="LightGray">

            <Grid.Resources>
                <Style TargetType="{x:Type TextBlock}">
                    <Setter Property="FontSize" Value="10"/>
                </Style>
            </Grid.Resources>

            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="22"/>
                <ColumnDefinition Width="20"/>
                <ColumnDefinition Width="123"/>
                <ColumnDefinition Width="30"/>
                <ColumnDefinition Width="20"/>
                <ColumnDefinition Width="20"/>
                <ColumnDefinition Width="20"/>
                <ColumnDefinition Width="20"/>
                <ColumnDefinition Width="20"/>
                <ColumnDefinition Width="20"/>
                <ColumnDefinition Width="20"/>
                <ColumnDefinition Width="20"/>
                <ColumnDefinition Width="20"/>
                <ColumnDefinition Width="20"/>
                <ColumnDefinition Width="20"/>
                <ColumnDefinition Width="20"/>
                <ColumnDefinition Width="20"/>
                <ColumnDefinition Width="20"/>
                <ColumnDefinition Width="20"/>
                <ColumnDefinition Width="20"/>
                <ColumnDefinition Width="20"/>
                <ColumnDefinition Width="20"/>
                <ColumnDefinition Width="20"/>
                <ColumnDefinition Width="20"/>
                <ColumnDefinition Width="20"/>
                <ColumnDefinition Width="20"/>
                <ColumnDefinition Width="20"/>
                <ColumnDefinition Width="20"/>
            </Grid.ColumnDefinitions>
            <Border Grid.Column="0" BorderThickness="1,1,0,1" BorderBrush="Black"/>
            <Border Grid.Column="1" BorderThickness="1,1,0,1" BorderBrush="Black"/>
            <Border Grid.Column="2" BorderThickness="1,1,0,1" BorderBrush="Black"/>
            <Border Grid.Column="3" BorderThickness="1,1,0,1" BorderBrush="Black"/>
            <Border Grid.Column="4" BorderThickness="1,1,0,1" BorderBrush="Black"/>
            <Border Grid.Column="5" BorderThickness="1,1,0,1" BorderBrush="Black"/>
            <Border Grid.Column="6" BorderThickness="1,1,0,1" BorderBrush="Black"/>
            <Border Grid.Column="7" BorderThickness="1,1,0,1" BorderBrush="Black"/>
            <Border Grid.Column="8" BorderThickness="1,1,0,1" BorderBrush="Black"/>
            <Border Grid.Column="9" BorderThickness="1,1,0,1" BorderBrush="Black"/>
            <Border Grid.Column="10" BorderThickness="1,1,0,1" BorderBrush="Black"/>
            <Border Grid.Column="11" BorderThickness="1,1,0,1" BorderBrush="Black"/>
            <Border Grid.Column="12" BorderThickness="1,1,0,1" BorderBrush="Black"/>
            <Border Grid.Column="13" BorderThickness="1,1,0,1" BorderBrush="Black"/>
            <Border Grid.Column="14" BorderThickness="1,1,0,1" BorderBrush="Black"/>
            <Border Grid.Column="15" BorderThickness="1,1,0,1" BorderBrush="Black"/>
            <Border Grid.Column="16" BorderThickness="1,1,0,1" BorderBrush="Black"/>
            <Border Grid.Column="17" BorderThickness="1,1,0,1" BorderBrush="Black"/>
            <Border Grid.Column="18" BorderThickness="1,1,0,1" BorderBrush="Black"/>
            <Border Grid.Column="19" BorderThickness="1,1,0,1" BorderBrush="Black"/>
            <Border Grid.Column="20" BorderThickness="1,1,0,1" BorderBrush="Black"/>
            <Border Grid.Column="21" BorderThickness="1,1,0,1" BorderBrush="Black"/>
            <Border Grid.Column="22" BorderThickness="1,1,0,1" BorderBrush="Black"/>
            <Border Grid.Column="23" BorderThickness="1,1,0,1" BorderBrush="Black"/>
            <Border Grid.Column="24" BorderThickness="1,1,0,1" BorderBrush="Black"/>
            <Border Grid.Column="25" BorderThickness="1,1,0,1" BorderBrush="Black"/>
            <Border Grid.Column="26" BorderThickness="1,1,0,1" BorderBrush="Black"/>
            <Border Grid.Column="27" BorderThickness="1,1,1,1" BorderBrush="Black"/>

            <TextBlock Text="NO" HorizontalAlignment="Center" VerticalAlignment="Center"  Margin="0" FontSize="12"/>
            <TextBlock Text="削" HorizontalAlignment="Center" Grid.Column="1" VerticalAlignment="Center" Margin="0" FontSize="12"/>
            <TextBlock Text="中項目名称" Grid.Row="0" Grid.Column="2" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0" FontSize="12"/>
            <TextBlock Text="回数" HorizontalAlignment="Center" Grid.Column="3" VerticalAlignment="Center" Margin="0" FontSize="12"/>
            <TextBlock Text="5" Grid.Row="0" Grid.Column="4" HorizontalAlignment="Center" VerticalAlignment="Center"  Margin="0"/>
            <TextBlock Text="6" Grid.Row="0" Grid.Column="5" HorizontalAlignment="Center" VerticalAlignment="Center"  Margin="0"/>
            <TextBlock Text="7" Grid.Row="0" Grid.Column="6" HorizontalAlignment="Center" VerticalAlignment="Center"  Margin="0"/>
            <TextBlock Text="8" Grid.Row="0" Grid.Column="7" HorizontalAlignment="Center" VerticalAlignment="Center"  Margin="0"/>
            <TextBlock Text="9" Grid.Row="0" Grid.Column="8" HorizontalAlignment="Center" VerticalAlignment="Center"  Margin="0"/>
            <TextBlock Text="10" Grid.Row="0" Grid.Column="9"  HorizontalAlignment="Center" VerticalAlignment="Center"  Margin="0"/>
            <TextBlock Text="11" Grid.Row="0" Grid.Column="10" HorizontalAlignment="Center" VerticalAlignment="Center"  Margin="0"/>
            <TextBlock Text="12" Grid.Row="0" Grid.Column="11" HorizontalAlignment="Center" VerticalAlignment="Center"  Margin="0"/>
            <TextBlock Text="13" Grid.Row="0" Grid.Column="12" HorizontalAlignment="Center" VerticalAlignment="Center"  Margin="0"/>
            <TextBlock Text="14" Grid.Row="0" Grid.Column="13" HorizontalAlignment="Center" VerticalAlignment="Center"  Margin="0"/>
            <TextBlock Text="15" Grid.Row="0" Grid.Column="14" HorizontalAlignment="Center" VerticalAlignment="Center"  Margin="0"/>
            <TextBlock Text="16" Grid.Row="0" Grid.Column="15" HorizontalAlignment="Center" VerticalAlignment="Center"  Margin="0"/>
            <TextBlock Text="17" Grid.Row="0" Grid.Column="16"  HorizontalAlignment="Center" VerticalAlignment="Center"  Margin="0"/>
            <TextBlock Text="18" Grid.Row="0" Grid.Column="17" HorizontalAlignment="Center" VerticalAlignment="Center"  Margin="0"/>
            <TextBlock Text="19" Grid.Row="0" Grid.Column="18" HorizontalAlignment="Center" VerticalAlignment="Center"  Margin="0"/>
            <TextBlock Text="20" Grid.Row="0" Grid.Column="19" HorizontalAlignment="Center" VerticalAlignment="Center"  Margin="0"/>
            <TextBlock Text="21" Grid.Row="0" Grid.Column="20" HorizontalAlignment="Center" VerticalAlignment="Center"  Margin="0"/>
            <TextBlock Text="20" Grid.Row="0" Grid.Column="21" HorizontalAlignment="Center" VerticalAlignment="Center"  Margin="0"/>
            <TextBlock Text="23" Grid.Row="0" Grid.Column="22"  HorizontalAlignment="Center" VerticalAlignment="Center"  Margin="0"/>
            <TextBlock Text="0" Grid.Row="0" Grid.Column="23" HorizontalAlignment="Center" VerticalAlignment="Center"  Margin="0"/>
            <TextBlock Text="1" Grid.Row="0" Grid.Column="24" HorizontalAlignment="Center" VerticalAlignment="Center"  Margin="0"/>
            <TextBlock Text="2" Grid.Row="0" Grid.Column="25" HorizontalAlignment="Center" VerticalAlignment="Center"  Margin="0"/>
            <TextBlock Text="3" Grid.Row="0" Grid.Column="26" HorizontalAlignment="Center" VerticalAlignment="Center"  Margin="0"/>
            <TextBlock Text="4" Grid.Row="0" Grid.Column="27" HorizontalAlignment="Center" VerticalAlignment="Center"  Margin="0"/>
        </Grid>

        <DataGrid Name="ScheduleDG" ItemsSource="{Binding ScheduleTable, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                      Grid.Row="1" AutoGenerateColumns="False"  HeadersVisibility="None"
                      IsReadOnly="False" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Hidden" 
                      SelectionUnit="CellOrRowHeader" SelectionMode="Extended" Padding="0" FontSize="10" BorderThickness="1" BorderBrush="Black" HorizontalAlignment="Left" Width="690"
                      Margin="0,-1,-2,0" Height="Auto" AllowDrop="True" RowHeight="18" 
                      PreviewMouseLeftButtonUp="ScheduleTable_PreviewMouseLeftButtonUp" 
                      PreviewMouseLeftButtonDown="ScheduleTable_PreviewMouseLeftButtonDown" MouseMove="ScheduleDG_MouseMove">
            <!--<i:Interaction.Triggers>
                <i:EventTrigger EventName="MouseLeftButtonUp">
                    <i:InvokeCommandAction Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}},
                                    Path=DataContext.CellSelectedCommand}"
                                    CommandParameter="{Binding SelectedCells, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}}" />
                </i:EventTrigger>
                <i:EventTrigger EventName="MouseLeftButtonDown">
                    <i:InvokeCommandAction Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}},
                                    Path=DataContext.StartCellCommand}"
                                    CommandParameter="{Binding CurrentCell, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}}" />
                </i:EventTrigger>
                <i:EventTrigger EventName="MouseRightClick">
                    <i:InvokeCommandAction Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}},
                                    Path=DataContext.RightClickCommand}"/>
                </i:EventTrigger>
            </i:Interaction.Triggers>-->

            <DataGrid.Columns>
                <DataGridTextColumn Header="NO" Width="22" IsReadOnly="True">
                    <DataGridTextColumn.HeaderStyle>
                        <Style TargetType="{x:Type DataGridColumnHeader}">
                            <Setter Property="FontSize" Value="10" />
                            <Setter Property="Margin" Value="0"/>
                        </Style>
                    </DataGridTextColumn.HeaderStyle>
                    <DataGridTextColumn.Binding>
                        <MultiBinding Converter="{StaticResource rowNumberConverter}">
                            <Binding />
                            <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}" />
                        </MultiBinding>
                    </DataGridTextColumn.Binding>
                </DataGridTextColumn>
                <DataGridTemplateColumn Header="削">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <CheckBox x:Name="TestCheckBox" VerticalAlignment="Center" HorizontalAlignment="Center"
                                      IsChecked="{Binding isSelected, Mode=OneWayToSource, UpdateSourceTrigger=PropertyChanged}"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
                <DataGridTextColumn Header="中項目名称" Binding="{Binding TaskName}" Width="123"/>
                <DataGridTextColumn Header="回数"  Width="30"/>

                <!--<DataGridTemplateColumn Header="5" MaxWidth="10">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock Background="{Binding _5, Converter={StaticResource  ResourceKey=hourSlotColorConverter}, UpdateSourceTrigger=PropertyChanged}"
                                     IsEnabled="False">
                                <i:Interaction.Triggers>
                                    <i:EventTrigger EventName="PreviewMouseDown">
                                        <i:InvokeCommandAction Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGrid}},
                                            Path=DataContext.StartCellCommand}"
                                            CommandParameter="{Binding CurrentCell, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}}" />
                                    </i:EventTrigger>
                                </i:Interaction.Triggers>
                            </TextBlock>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>

                </DataGridTemplateColumn>-->

                <DataGridTextColumn Header="5" MaxWidth="10" FontSize="8" Width="10" IsReadOnly="True">
                    <DataGridTextColumn.ElementStyle>
                        <Style TargetType="{x:Type TextBlock}">
                            <Setter Property="Background" Value="{Binding _5, Converter={StaticResource ResourceKey=hourSlotColorConverter}, UpdateSourceTrigger=PropertyChanged}"/>
                            <Setter Property="Margin" Value="-1" />
                        </Style>
                    </DataGridTextColumn.ElementStyle>
                </DataGridTextColumn>

                <DataGridTextColumn Header="" MaxWidth="10" IsReadOnly="True">
                    <DataGridTextColumn.ElementStyle>
                        <Style TargetType="{x:Type TextBlock}">
                            <Setter Property="Background" Value="{Binding _5_5, Converter={StaticResource ResourceKey=hourSlotColorConverter}, UpdateSourceTrigger=PropertyChanged}"/>
                            <Setter Property="Margin" Value="-1" />
                        </Style>
                    </DataGridTextColumn.ElementStyle>
                </DataGridTextColumn>

                <DataGridTextColumn Header="6" MaxWidth="10" IsReadOnly="True">
                    <DataGridTextColumn.ElementStyle>
                        <Style TargetType="{x:Type TextBlock}">
                            <Setter Property="Background" Value="{Binding _6, Converter={StaticResource ResourceKey=hourSlotColorConverter}, UpdateSourceTrigger=PropertyChanged}"/>
                            <Setter Property="Margin" Value="-1" />
                        </Style>
                    </DataGridTextColumn.ElementStyle>
                </DataGridTextColumn>

                <DataGridTextColumn Header="" MaxWidth="10" IsReadOnly="True" >
                    <DataGridTextColumn.ElementStyle>
                        <Style TargetType="{x:Type TextBlock}">
                            <Setter Property="Background" Value="{Binding _3_5, Converter={StaticResource ResourceKey=hourSlotColorConverter}, UpdateSourceTrigger=PropertyChanged}"/>
                            <Setter Property="Margin" Value="-1" />
                        </Style>
                    </DataGridTextColumn.ElementStyle>
                </DataGridTextColumn>

                <DataGridTextColumn Header="4" MaxWidth="10" IsReadOnly="True" >
                    <DataGridTextColumn.ElementStyle>
                        <Style TargetType="{x:Type TextBlock}">
                            <Setter Property="Background" Value="{Binding _4, Converter={StaticResource ResourceKey=hourSlotColorConverter}, UpdateSourceTrigger=PropertyChanged}"/>
                            <Setter Property="Margin" Value="-1" />
                        </Style>
                    </DataGridTextColumn.ElementStyle>
                </DataGridTextColumn>

                <DataGridTextColumn Header="" MaxWidth="9"  IsReadOnly="True">
                    <DataGridTextColumn.ElementStyle>
                        <Style TargetType="{x:Type TextBlock}">
                            <Setter Property="Background" Value="{Binding _4_5, Converter={StaticResource ResourceKey=hourSlotColorConverter}, UpdateSourceTrigger=PropertyChanged}"/>
                            <Setter Property="Margin" Value="-1" />
                        </Style>
                    </DataGridTextColumn.ElementStyle>
                </DataGridTextColumn>

            </DataGrid.Columns>
        </DataGrid>

    </Grid>


</UserControl>

the code-behind

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel.Composition;
using MainModule.Infrastructure.Interface;
using Widget5.ViewModel;

namespace Widget5.View
{
    /// <summary>
    /// Interaction logic for ExcelDisplay.xaml
    /// </summary>
    [Export(typeof(IMainModulePage))]
    [ExportMetadata("WidgetName", "Widget5")]
    [ExportMetadata("MenuNo", 1)]
    [ExportMetadata("PageTitle", "WorkItemsPage")]
    public partial class WorkItemsDisplay : UserControl, IMainModulePage
    {
        public WorkItemsDisplay()
        {
            DataContext = eVM;
            InitializeComponent();
        }

        // inherit
        public string WidgetName
        {
            get { return "Widget5"; }
        }

        public int MenuNo
        {
            get { return 1; }
        }

        public string PageTitle
        {
            get { return "WorkItemsPage"; }
        }

        ExcelGridViewModel eVM = new ExcelGridViewModel();
        bool isClicked;
        List<int> trueCells;
        bool hasMoved;

        private void ScheduleTable_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            DependencyObject dep = (DependencyObject)e.OriginalSource;

            // iteratively traverse the visual tree
            while ((dep != null) &&
                    !(dep is DataGridCell))
            {
                dep = VisualTreeHelper.GetParent(dep);
            }

            if (dep == null)
                return;

            if (dep is DataGridCell)
            {
                DataGridCell cell = dep as DataGridCell;
                DataGridCellInfo cellInfo = new DataGridCellInfo(cell);

                while ((dep != null) && !(dep is DataGridRow))
                {
                    dep = VisualTreeHelper.GetParent(dep);
                }

                DataGridRow row = dep as DataGridRow;

                hasMoved = false;

                if (eVM.DoEndCell(cell, row, hasMoved))
                    ScheduleDG.UnselectAllCells();
                ScheduleDG.CurrentCell = cellInfo;

            }

            isClicked = false;

        }

        private void ScheduleTable_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            DependencyObject dep = (DependencyObject)e.OriginalSource;


            // iteratively traverse the visual tree
            while ((dep != null) &&
                    !(dep is DataGridCell))
            {
                dep = VisualTreeHelper.GetParent(dep);
            }

            if (dep == null)
                return;

            if (dep is DataGridCell)
            {
                DataGridCell cell = dep as DataGridCell;

                while ((dep != null) && !(dep is DataGridRow))
                {
                    dep = VisualTreeHelper.GetParent(dep);
                }

                DataGridRow row = dep as DataGridRow;

                trueCells = eVM.DoStartCell(cell, row);
            }

            isClicked = true;
        }

        private void Grid_MouseRightButtonUp(object sender, MouseButtonEventArgs e)
        {
            e.Handled = true;
        }

        private void ScheduleDG_MouseMove(object sender, MouseEventArgs e)
        {
            DependencyObject dep = (DependencyObject)e.OriginalSource;

            // iteratively traverse the visual tree
            while ((dep != null) &&
                    !(dep is DataGridCell))
            {
                dep = VisualTreeHelper.GetParent(dep);
            }

            if (dep == null)
                return;

            if (dep is DataGridCell)
            {
                DataGridCell cell = dep as DataGridCell;
                DataGridCellInfo cellInfo = new DataGridCellInfo(cell);

                while ((dep != null) && !(dep is DataGridRow))
                {
                    dep = VisualTreeHelper.GetParent(dep);
                }

                DataGridRow row = dep as DataGridRow;

                if (isClicked && (trueCells.Count <= 1))
                {
                    hasMoved = true;
                    eVM.DoEndCell(cell, row, hasMoved);
                }
            }
        }

        private void Grid_MouseUp(object sender, MouseButtonEventArgs e)
        {
            isClicked = false;
            hasMoved = false;
        }


    }
}

EDIT

I proceeded to multibind the datagridcell 's column and datacontext properties as parameters for my command . An option I started before but set aside due to time constraints. Instead of looking for the datagridrow's index, I used the datacontext to compare to my viewmodel . Did the trick.

The general way to achieve your requirement is to implement an ICommand type Attached Property for each event that you want to replace. The basic idea is this... add an ICommand Attached Property with a PropertyChangedCallback handler. In this handler (which will be called when an ICommand is data bound to this property), attach a handler to the event that you want to handle. Then, when that event is called, just execute the ICommand instance. So you can handle the event in your view model via the ICommand instance. Here is an example using the PreviewKeyDown event:

public static DependencyProperty OnEnterKeyDownProperty = DependencyProperty.RegisterAttached("OnEnterKeyDown", typeof(ICommand), typeof(TextBoxProperties), new UIPropertyMetadata(null, OnOnEnterKeyDownChanged));

public static ICommand GetOnEnterKeyDown(DependencyObject dependencyObject)
{
    return (ICommand)dependencyObject.GetValue(OnEnterKeyDownProperty);
}

public static void SetOnEnterKeyDown(DependencyObject dependencyObject, ICommand value)
{
    dependencyObject.SetValue(OnEnterKeyDownProperty, value);
}

public static void OnOnEnterKeyDownChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
    TextBox textBox = dependencyObject as TextBox;
    if (e.OldValue == null && e.NewValue != null) textBox.PreviewKeyDown += TextBox_OnEnterKeyDown;
    else if (e.OldValue != null && e.NewValue == null) textBox.PreviewKeyDown -= TextBox_OnEnterKeyDown;
}

private static void TextBox_OnEnterKeyDown(object sender, KeyEventArgs e)
{
    if (e.Key == Key.Enter || e.Key == Key.Return)
    {
        TextBox textBox = sender as TextBox;
        ICommand command = GetOnEnterKeyDown(textBox);
        if (command != null && command.CanExecute(textBox)) command.Execute(textBox);
    }
    e.Handled = false;
}

Alternative would be to work with properties DataGrid already provides to you and/or to define few other attached properties supporting you to get the job done.

I would try to work with properties like SelectedItem, SelectedValue, CurrentItem, CurrentCell.

Futhermore if a behavior couldnt be handled with those properties from above I would create an attached property and use a style for cells with triggers changing the attached property. Binding will transmit all the changes from the attached property to the ViewModel.

In the end you will have just communication between ViewModel and View.

Here are few links:

http://msdn.microsoft.com/en-us/library/system.windows.controls.datagrid%28v=vs.110%29.aspx

http://msdn.microsoft.com/en-us/library/system.windows.controls.datagrid.currentitem%28v=vs.110%29.aspx

http://msdn.microsoft.com/en-us/library/system.windows.controls.primitives.selector.selectedvalue%28v=vs.110%29.aspx

http://msdn.microsoft.com/en-us/library/system.windows.controls.primitives.selector.selecteditem%28v=vs.110%29.aspx

They should be all bindable

Edit:

Link to MSDN MultiBinding Page:

http://msdn.microsoft.com/en-us/library/system.windows.data.multibinding%28v=vs.110%29.aspx

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM