突出显示DataGrid中的一个项目

本文关键字:一个 项目 显示 DataGrid | 更新日期: 2023-09-27 18:10:55

我在DataGrid中显示Cars,并想突出显示一辆特殊的汽车,CurrentlySelectedCar

当用户双击一辆车时,这辆车在我的MainViewModel中保存为CurrentlySelectedCar。现在,每当用户返回到DataGrid时,我想突出显示这一行,例如,通过使用红色背景。

我已经知道如何根据某些值突出显示DataGrid中的行,但在我的情况下,我所拥有的只是CurrentlySelectedCar。

My First try:

            <Style TargetType="DataGridRow">
                <Style.Triggers>
                    <!-- not working-->
                    <DataTrigger Binding="{Binding CurrentlySelectedCar}" >
                        <Setter Property="Background" Value="Red"></Setter>
                    </DataTrigger>
                </Style.Triggers>
            </Style>

第二次尝试:

            <Style TargetType="DataGridRow">
                <Style.Triggers>
                    <!-- not working either, "Binding can only be set on DependencyProperty of DependecyObject"-->
                    <DataTrigger Binding="{Binding Guid}" Value="{Binding CurrentlySelectedCar.Guid}" >
                        <Setter Property="Background" Value="Red"></Setter>
                    </DataTrigger>
                </Style.Triggers>
            </Style>

我如何用这些信息突出显示行?

突出显示DataGrid中的一个项目

我认为你必须做这个答案中描述的事情:在DataTrigger条件下使用绑定

<Style TargetType="DataGridRow">
  <Style.Triggers>
    <DataTrigger Value="True">
      <DataTrigger.Binding>
        <MultiBinding Converter="{StaticResource someMultiConverter}">
          <Binding Path="Guid"></Binding>
          <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type Datagrid}}" Path="CurrentlySelectedCar.Guid"></Binding>
        </MultiBinding>
      </DataTrigger.Binding>
      <Setter Property="Background" Value="Red"></Setter>
    </DataTrigger>
  </Style.Triggers>
</Style>

你必须写一个multiconverter,当两个Guid相等时返回true

试试下面的方法,因为每个数据网格行都有一个IsSelected属性,所以可以直接绑定到它。

<DataGrid EnableRowVirtualization="False">
   <DataGrid.Resources>
       <Style TargetType="DataGridRow">
            <Style.Triggers>
                <DataTrigger Binding="{Binding IsSelected}" >
                   <Setter Property="Background" Value="Red"></Setter>
                </DataTrigger>
             </Style.Triggers>
       </Style>
  </DataGrid.Resources>
</DataGrid>

更新响应

现在的问题是你的DataContext是DataGridRow,它没有访问MainViewModel。您可以通过将DataGridRow传递给能够感知当前MainViewModel的转换器来解决这个问题。然而,它有很多代码,很难理解。

<Window>
  <Window.Resources>
    <local:IsCurrentlySelectedCarConverter x:Key="IsCurrentlySelectedCarConverter" />
  </Window.Resources>
   ...
  <DataTrigger Binding="{Binding 
        Path=DataContext, 
        Converter={StaticResource IsCurrentlySelectedCarConverter}}" >
    <Setter Property="Background" Value="Red" />
  </DataTrigger>
</Window>

这里是相应的转换器

public class IsCurrentlySelectedConverter : IValueConverter
{
   public MainViewModel MainViewModel { get; set;}
   public object Convert(object value, ....)
   {
      return (value == MainViewModel.CurrentlySelectedCar);              
   }
}

,您需要在视图

中手动连接转换器的MainViewModel。
this.Resources["IsCurrentlySelectedCarConverter"].MainViewModel = _mainViewModel;

,此时你不得不质疑已创建的怪物的可维护性。

最好将每个Car替换为CarViewModel,这样它就有一个称为IsSelected的属性,您可以在代码中维护它。在我看来,下面的内容更容易理解实际情况。

public class CarViewModel : INotifyPropertyChanged
{
      public MainViewModel { get; set; }
      public bool IsSelected { get { return this == MainViewModel.CurrentlySelectedCar; } }
      // Call RaisePropertyChanged("IsSelected") whenever
      // CurrentlySelectedCar is changed
      public void RaisePropertyChanged(string propertyName) 
      {
          if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName);
      }
}