【问题标题】:C# WPF MVVM DataGrid MouseBinding for rows onlyC# WPF MVVM DataGrid MouseBinding 仅用于行
【发布时间】:2020-02-13 20:25:02
【问题描述】:

我有一个带有 DataGrid 的 WPF 应用程序,我希望用户能够双击一行以打开一个编辑对话框。

所以我在 ViewModel 中添加了一个 SelectedItem 属性,并将 InputBinding 添加到我的 Grid 中。现在我的 ViewModel 中有一个命令,当用户双击网格时会触发该命令。我也得到了正确的选定项目。到目前为止一切顺利。

问题是,当用户点击网格上的一些空白区域时,事件也会被触发(我在图片上标记了它)..

用户应该不能在空白处执行双击操作。因为在 SelectedItem 未更改的情况下触发了该事件。所以这是错误的。

我的 DataGrid 的 XAML 代码:

<DataGrid Name="dgSafetyFunction" AutoGenerateColumns="False" ItemsSource="{Binding SafetyFunctionList}" Margin="0,0,0,45" 
              SelectedItem="{Binding Path=SelectedItem, Mode=TwoWay}" IsReadOnly="True" IsSynchronizedWithCurrentItem="True" SelectionUnit="FullRow">
    <DataGrid.InputBindings>
        <MouseBinding
            MouseAction="LeftDoubleClick"
            Command="{Binding OnDataGridDoubleClickCommand}"/>
    </DataGrid.InputBindings>
    <DataGrid.Columns>
        <DataGridTextColumn Header="ID" Binding="{Binding ID}"/>
        <DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
        <DataGridTextColumn Header="Beschreibung" Binding="{Binding Description}"/>
        <DataGridTextColumn Header="Projekt ID" Binding="{Binding ProjectID}"/>
    </DataGrid.Columns>
</DataGrid>

SelectedItem 属性:

private SafetyFunctionModel m_SelectedItem;

public SafetyFunctionModel SelectedItem
{
    get
    {
        return m_SelectedItem;
    }
    set
    {
        if (value != m_SelectedItem)
        {
            m_SelectedItem = value;
            OnPropertyChanged("SelectedItem");
        }
    }
}

如何通过 MVVM 方式解决此问题?

问候

【问题讨论】:

标签: c# wpf events mvvm datagrid


【解决方案1】:

定义一个CellTemplate 并将MouseBinding 移动到这个的根元素:

<DataGrid Name="dgSafetyFunction" AutoGenerateColumns="False" ItemsSource="{Binding SafetyFunctionList}" Margin="0,0,0,45" 
          SelectedItem="{Binding Path=SelectedItem, Mode=TwoWay}" IsReadOnly="True" IsSynchronizedWithCurrentItem="True" SelectionUnit="FullRow">
    <DataGrid.Columns>
        <DataGridTextColumn Header="ID" Binding="{Binding ID}"/>
        <DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
        <DataGridTextColumn Header="Beschreibung" Binding="{Binding Description}"/>
        <DataGridTextColumn Header="Projekt ID" Binding="{Binding ProjectID}"/>
    </DataGrid.Columns>
    <DataGrid.CellStyle>
        <Style TargetType="{x:Type DataGridCell}">
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="BorderBrush" Value="Transparent"/>
            <Setter Property="BorderThickness" Value="1"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type DataGridCell}">
                        <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
                            <ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                            <Border.InputBindings>
                                <MouseBinding MouseAction="LeftDoubleClick" Command="{Binding DataContext.OnDataGridDoubleClickCommand, 
                                            RelativeSource={RelativeSource AncestorType=DataGrid}}"/>
                            </Border.InputBindings>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            <Style.Triggers>
                <Trigger Property="IsSelected" Value="True">
                    <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
                    <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
                    <Setter Property="BorderBrush" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
                </Trigger>
                <Trigger Property="IsKeyboardFocusWithin" Value="True">
                    <Setter Property="BorderBrush" Value="{DynamicResource {x:Static DataGrid.FocusBorderBrushKey}}"/>
                </Trigger>
                <MultiTrigger>
                    <MultiTrigger.Conditions>
                        <Condition Property="IsSelected" Value="true"/>
                        <Condition Property="Selector.IsSelectionActive" Value="false"/>
                    </MultiTrigger.Conditions>
                    <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"/>
                    <Setter Property="BorderBrush" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"/>
                    <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightTextBrushKey}}"/>
                </MultiTrigger>
                <Trigger Property="IsEnabled" Value="false">
                    <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                </Trigger>
            </Style.Triggers>
        </Style>
    </DataGrid.CellStyle>
</DataGrid>

【讨论】:

    【解决方案2】:

    你可以为DataGridRow设置事件,像这样

    <DataGrid.Resources>
        <Style TargetType="DataGridRow">
            <Setter Property="command:CommandBehavior.Event" Value="MouseDoubleClick"/>
            <Setter Property="command:CommandBehavior.Command" Value="{Binding DataContext.MouseDoubleClickCommand, RelativeSource={RelativeSource FindAncestor, AncestorType=DataGrid}}"/>
        </Style>
    </DataGrid.Resources>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-05-16
      • 2021-07-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-02
      • 2011-03-19
      • 2013-08-03
      相关资源
      最近更新 更多