已选择行时 WPF MVVM DataGrid DoubleClick 不起作用

WPF MVVM DataGrid DoubleClick not working when row is already selected

所以我遇到了与 this question 相同的问题。 然而,这个解决方案似乎是代码隐藏(并且已有 4 年历史)但我使用的是 MVVM。时间可能已经为此带来了更好的解决方案。

有人知道在选中 DataGridRow 后双击它的方法吗?

这是我的 XAML:

<DataGrid x:Name="ContactsResult" 
          AlternatingRowBackground="Transparent"
          AutoGenerateColumns="False" 
          BorderBrush="{StaticResource DarkBlueBrush}"
          BorderThickness="1"
          CanUserAddRows="False" 
          FontFamily="{StaticResource DefaultFont}"
          GridLinesVisibility="None"
          HeadersVisibility="Column"
          IsReadOnly="True"
          ItemsSource="{Binding Results, Mode=TwoWay}"
          SelectedItem="{Binding SelectedItem, Mode=TwoWay}" 
          >

          <DataGrid.InputBindings>
              <MouseBinding Gesture="LeftDoubleClick" 
                            Command="{Binding DetailsCommand}"
                            CommandParameter="{Binding ElementName=ContactsResult, Path=SelectedItem.ContactId}"
                            />
          </DataGrid.InputBindings>

          <DataGrid.Columns>
              <DataGridTextColumn x:Name="contactLastNameColumn" 
                                  Binding="{Binding Name_LastSufFirstMidSal}"
                                  ElementStyle="{StaticResource dgCellPadding5}"                      Header="Contact Name" 
                                  Width="Auto" 
                                  />
              <DataGridTextColumn x:Name="companyNameColumn"
                                  ElementStyle="{StaticResource dgCellPadding5}"                      Header="Company Name"
                                  Width="Auto"
                                  />
              <DataGridTextColumn x:Name="CityColumn" 
                                  Binding="{Binding MailingAddress.City}" 
                                  ElementStyle="{StaticResource dgCellPadding5}"                      Header="Mailing City"
                                  Width="Auto"
                                  />
              <DataGridTextColumn x:Name="StateColumn" 
                                  Binding="{Binding MailingAddress.StateOrProvince}"      ElementStyle="{StaticResource dgCellPadding5}"                      Header="Mailing State" 
                                  Width="Auto"
                                  />
          </DataGrid.Columns>
</DataGrid>

编辑

元素样式

<Style x:Key="dgCellPadding5" TargetType="{x:Type TextBlock}">
    <Setter Property="Margin" Value="5" />
</Style>

以下示例针对 .NET 4.7.1,触发双击命令(无论选择状态如何)。我从上面包含了您引用的样式。您的代码与此有什么不同吗?

<Window x:Class="WpfApp1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:wpfApp1="clr-namespace:WpfApp1"
    mc:Ignorable="d"
    Title="MainWindow" Height="450" Width="800">
<Window.DataContext>
    <wpfApp1:ViewModel />
</Window.DataContext>
<Window.Resources>
    <Style x:Key="dgCellPadding5" TargetType="{x:Type TextBlock}">
        <Setter Property="Margin" Value="5" />
    </Style>
</Window.Resources>
<DataGrid x:Name="ContactsResult"
          AlternatingRowBackground="Transparent"
          AutoGenerateColumns="False"
          BorderThickness="1"
          CanUserAddRows="False"
          GridLinesVisibility="None"
          HeadersVisibility="Column"
          IsReadOnly="True"
          ItemsSource="{Binding Contacts}"
          SelectedItem="{Binding SelectedContact, Mode=TwoWay}">

    <DataGrid.InputBindings>
        <MouseBinding Gesture="LeftDoubleClick"
                      Command="{Binding Command}"
                      CommandParameter="{Binding ElementName=ContactsResult, Path=SelectedItem}" />
    </DataGrid.InputBindings>

    <DataGrid.Columns>
        <DataGridTextColumn ElementStyle="{StaticResource dgCellPadding5}"
                            Binding="{Binding ContactName}"
                            Header="Contact Name"
                            Width="Auto" />
        <DataGridTextColumn ElementStyle="{StaticResource dgCellPadding5}" Header="Company Name"
                            Binding="{Binding CompanyName}"
                            Width="Auto" />
        <DataGridTextColumn Binding="{Binding City}" Header="Mailing City"
                            Width="Auto" ElementStyle="{StaticResource dgCellPadding5}" />
        <DataGridTextColumn Binding="{Binding State}" Header="Mailing State"
                            Width="Auto" ElementStyle="{StaticResource dgCellPadding5}" />
    </DataGrid.Columns>
</DataGrid>

using System;
using System.Diagnostics;
using System.Windows.Input;
using Prism.Commands;
using Prism.Mvvm;

namespace WpfApp1
{
    public class ViewModel : BindableBase
    {
        public ContactInfo[] Contacts
        {
            get;
        } =
        {
            new ContactInfo
            {
                ContactName = "First",
                CompanyName = "Acme",
                City = "Somewhere",
                State = "CA"
            },
            new ContactInfo
            {
                ContactName = "Second",
                CompanyName = "Acme",
                City = "Somewhere",
                State = "CA"
            },
            new ContactInfo
            {
                ContactName = "Third",
                CompanyName = "Acme",
                City = "Somewhere",
                State = "CA"
            },
            new ContactInfo
            {
                ContactName = "Fourth",
                CompanyName = "Acme",
                City = "Somewhere",
                State = "CA"
            }
        };

        private ContactInfo _selectedContact;

        public ContactInfo SelectedContact
        {
            get => _selectedContact;
            set => SetProperty(ref _selectedContact, value);
        }

        public ICommand Command
        {
            get;
        } = new DelegateCommand<ContactInfo>(ci => Debug.WriteLine($"{ci.ContactName} {DateTime.Now}"));

        public ICommand OtherCommand
        {
            get;
        } = new DelegateCommand<string>(s => Debug.WriteLine($"{s} {DateTime.Now}"));
    }

    public class ContactInfo
    {
        public string ContactName
        {
            get;
            set;
        }

        public string CompanyName
        {
            get; set;
        }

        public string City
        {
            get;
            set;
        }

        public string State
        {
            get;
            set;
        }
    }
}

我使用棱镜框架,这是我的代码:

   xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
 <controls:CustomDataGrid Grid.Row="2" 
                   SelectedItem="{Binding ModelItem}"
                  ItemsSource="{Binding ModelList}"
                  IsReadOnly="True"
                  Style="{StaticResource DataTriggerDataGridStyle}">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="MouseDoubleClick">
                    <i:InvokeCommandAction Command="{Binding BtnNoticeViewCommand, IsAsync=True}"/>
                </i:EventTrigger>
            </i:Interaction.Triggers>

所以为了达到我的目标,我决定走另一条路。

首先,我从网格开始,并使用属性 Grid.IsSharedSizeScope="True"。在这个网格中,我创建了一个网格和一个 ItemsControl(在数据模板中有一个网格)。这给了我数据网格的外观。

其次,在 itemscontrol 中,我将 InputBindings 添加到每个项目以实现所需的行为。这是我想出的:

        <Border Grid.Row="2"
                BorderBrush="{StaticResource BackgroundTitleBarBrush}"
                BorderThickness="1"
                Visibility="{Binding ResultGridVisible, Converter={local:BooleanToVisibilityValueConverter}, ConverterParameter=True}"
                    >

            <Grid Background="White" 
              Grid.Row="2"
              Grid.IsSharedSizeScope="True"
              >
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                </Grid.RowDefinitions>

                <Border BorderBrush="{StaticResource SeperatorDarkBlueBrush}" 
                    BorderThickness="0 0 0 1"
                    Margin="5 0"
                    Padding="3 5"
                    Grid.Row="0">
                    <Grid VerticalAlignment="Center">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition SharedSizeGroup="A" Width="150"/>
                            <ColumnDefinition SharedSizeGroup="B" Width="200"/>
                            <ColumnDefinition SharedSizeGroup="C" Width="100"/>
                            <ColumnDefinition SharedSizeGroup="D" Width="75"/>
                            <ColumnDefinition SharedSizeGroup="E" Width="100"/>
                            <ColumnDefinition SharedSizeGroup="F" Width="50"/>
                        </Grid.ColumnDefinitions>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto"/>
                            <RowDefinition Height="Auto"/>
                        </Grid.RowDefinitions>

                        <TextBlock FontWeight="Bold"
                                   Foreground="{StaticResource BackgroundTitleBarBrush}"
                                   Grid.Column="0"
                                   Text="Contact Name"
                                   />
                        <TextBlock FontWeight="Bold"
                                   Foreground="{StaticResource BackgroundTitleBarBrush}"
                                   Grid.Column="1"
                                   Text="Company Name"
                                   />
                        <TextBlock FontWeight="Bold"
                                   Foreground="{StaticResource BackgroundTitleBarBrush}"
                                   Grid.Column="2"
                                   Grid.ColumnSpan="2"
                                   Text="Mailing"
                                   />
                        <TextBlock FontWeight="Bold"
                                   Foreground="{StaticResource BackgroundTitleBarBrush}"
                                   Grid.Column="2"
                                   Grid.Row="1"
                                   Text="City"
                                   />
                        <TextBlock FontWeight="Bold"
                                   Foreground="{StaticResource BackgroundTitleBarBrush}"
                                   Grid.Column="3"
                                   Grid.Row="1"
                                   Text="State"
                                   />
                        <TextBlock FontWeight="Bold"
                                   Foreground="{StaticResource BackgroundTitleBarBrush}"
                                   Grid.Column="4"
                                   Grid.ColumnSpan="2"
                                   Text="Other"
                                   />
                        <TextBlock FontWeight="Bold"
                                   Foreground="{StaticResource BackgroundTitleBarBrush}"
                                   Grid.Column="4"
                                   Grid.Row="1"
                                   Text="City"
                                   />
                        <TextBlock FontWeight="Bold"
                                   Foreground="{StaticResource BackgroundTitleBarBrush}"
                                   Grid.Column="5"
                                   Grid.Row="1"
                                   Text="State"
                                   />
                    </Grid>
                </Border>

                <ScrollViewer Grid.Row="1" 
                              HorizontalScrollBarVisibility="Disabled"
                              MaxHeight="350"                              
                              VerticalScrollBarVisibility="Auto" 
                              >
                    <ItemsControl ItemsSource="{Binding Results}">
                        <ItemsControl.ItemTemplate>
                            <DataTemplate>
                                <Border x:Name="Container" 
                                        BorderBrush="{StaticResource SeperatorLightBlueBrush}" 
                                        BorderThickness="0 0 0 1"
                                        Margin="5 0"
                                        Padding="3 5"
                                        >
                                    <Border.InputBindings>
                                        <MouseBinding MouseAction="LeftClick"
                                                      Command="{Binding Path=DataContext.DetailsCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:BasePage}}}"
                                                      CommandParameter="{Binding ContactId}"
                                                      />
                                        <MouseBinding MouseAction="RightClick"
                                                      Command="{Binding Path=DataContext.NewWindowDetailsCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:BasePage}}}"
                                                      CommandParameter="{Binding ContactId}"
                                                      />
                                    </Border.InputBindings>

                                    <Grid VerticalAlignment="Center">
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition SharedSizeGroup="A"/>
                                            <ColumnDefinition SharedSizeGroup="B"/>
                                            <ColumnDefinition SharedSizeGroup="C"/>
                                            <ColumnDefinition SharedSizeGroup="D"/>
                                            <ColumnDefinition SharedSizeGroup="E"/>
                                            <ColumnDefinition SharedSizeGroup="F"/>
                                        </Grid.ColumnDefinitions>

                                        <TextBlock FontFamily="{StaticResource DefaultFont}" 
                                                   Grid.Column="0"
                                                   Text="{Binding Name_LastSufFirstMidSal}"
                                                   VerticalAlignment="Center"
                                                   />
                                        <TextBlock FontFamily="{StaticResource DefaultFont}" 
                                                   Grid.Column="1"
                                                   Text="{Binding Company}"
                                                   VerticalAlignment="Center"
                                                   />
                                        <TextBlock FontFamily="{StaticResource DefaultFont}" 
                                                   Grid.Column="2"
                                                   Text="{Binding MailingAddress.City}"
                                                   VerticalAlignment="Center"
                                                   />
                                        <TextBlock FontFamily="{StaticResource DefaultFont}" 
                                                   Grid.Column="3"
                                                   Text="{Binding MailingAddress.StateOrProvince}"
                                                   VerticalAlignment="Center"
                                                   />
                                        <TextBlock FontFamily="{StaticResource DefaultFont}" 
                                                   Grid.Column="4"
                                                   Text="{Binding OtherAddress.City}"
                                                   VerticalAlignment="Center"
                                                   />
                                        <TextBlock FontFamily="{StaticResource DefaultFont}" 
                                                   Grid.Column="5"
                                                   Text="{Binding OtherAddress.StateOrProvince}"
                                                   VerticalAlignment="Center"
                                                   />
                                    </Grid>
                                </Border>

                                <DataTemplate.Triggers>
                                    <Trigger Property="IsMouseOver" Value="True">
                                        <Setter TargetName="Container" Property="Background" Value="{StaticResource BackgroundLightBlueBrush}"/>
                                    </Trigger>
                                </DataTemplate.Triggers>

                            </DataTemplate>
                        </ItemsControl.ItemTemplate>
                    </ItemsControl>
                </ScrollViewer>

                <Border Grid.Row="1" Panel.ZIndex="1" Visibility="{Binding NoRecordsFound, Converter={local:BooleanToCollapsedVisibilityValueConverter}, ConverterParameter=True, Mode=TwoWay}">
                    <TextBlock Text="No Records Found"
                               Margin="5 0"
                               Padding="3 5"
                               />
                </Border>

            </Grid>

        </Border>