【问题标题】:MVVM Datagrid first row selected by default but not highlightedMVVM Datagrid 第一行默认选中但未突出显示
【发布时间】:2014-10-18 15:31:53
【问题描述】:

我有一个绑定到我的 ViewModel 上的集合的数据网格。当窗口加载时,填充数据网格并设置 SelectedItem。 (我知道这一点是因为我有一个绑定到所选项目的详细视图。)但是该行没有突出显示。如果我单击该行,那么它将突出显示并正常工作。

如何使选定的行在默认选择时突出显示?

<DataGrid IsSynchronizedWithCurrentItem="True" SelectionUnit="FullRow"  RowHeaderWidth="0"  VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Visible"  IsReadOnly="True" ItemsSource="{Binding Items}"  SelectedItem="{Binding Path=SelectedItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" AutoGenerateColumns="False">
    <DataGrid.Columns>                    
        <DataGridTextColumn Header="Run Date" Binding="{Binding Path=RunDate, StringFormat={}{0:MM-dd-yy HH:mm:ss} }"  />
        <DataGridTextColumn Header="Description" Binding="{Binding Description}" />
        <DataGridTextColumn Header="Duration" Binding="{Binding Duration}" />
        <DataGridTextColumn Header="Deviation" Binding="{Binding Deviation}" />
    </DataGrid.Columns>
</DataGrid>

【问题讨论】:

  • 我猜您正确设置了所选项目,但不要关注DataGrid。据我所知,DataGrid 不会突出显示选定的行,如果 Grid 本身或其子项之一未获得焦点。
  • 绑定后是否有一种 MVVM“兼容”方式来表示 Set focus to datagrid?虽然我认为我可以在后面的视图代码上做到这一点,而不必违背模式。
  • 您可以查看this answer 关于通过 MVVM 设置焦点元素的信息。但是,在您的视图中设置代码隐藏会容易得多。此外,如果您设置DataGridSelectedItem 属性,它至少应该以浅灰色突出显示。一旦您需要以蓝色突出显示,您应该重新考虑更新视图模型的SelectedItem 属性的方法。您可能希望通过相同的方法将SelectedItem 和焦点设置为UIElement
  • @jrandomuser 我认为在代码隐藏中设置焦点绝对兼容 MVVM 模式,因为它只与视图相关。
  • @Artholl:代码隐藏与 MVVM 兼容,但它减少了功能的重用,我会将其作为一种行为来实现。

标签: c# wpf xaml mvvm datagrid


【解决方案1】:

您只需要一个样式来说明如何处理 SelectedItem

<Style x:Key="SomeStyle" TargetType="{x:Type DataGridRow}" >
        <Style.Triggers>
            <Trigger Property="DataGridRow.IsSelected" Value="True">
                <Setter Property="Background" Value="Red" />
            </Trigger>
        </Style.Triggers>
    </Style>

然后将其应用到您的datagrid xaml

<DataGrid RowStyle="{StaticResource SomeStyle}"...

【讨论】:

    【解决方案2】:

    正如我在评论中提到的,有可能将网格集中在随着行为而改变的选择上。所以你会得到,该选择将突出显示:

    using System.Windows.Controls;
    using System.Windows.Interactivity;
    
    public class FocusGridOnSelectionChanged : Behavior<DataGrid>
    {
        protected override void OnAttached()
        {
            base.OnAttached();
    
            AssociatedObject.SelectionChanged += AssociatedObject_SelectionChanged;
        }
    
        private void AssociatedObject_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            AssociatedObject?.Focus();
        }
    
        protected override void OnDetaching()
        {
            AssociatedObject.SelectionChanged -= AssociatedObject_SelectionChanged;
    
            base.OnDetaching();
        }
    
    }
    
    
    xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
    <DataGrid ... >
    
        <i:Interaction.Behaviors>
            <yourbehaviorsns:FocusGridOnSelectionChanged/>
        </i:Interaction.Behaviors>
    
        ...
    
    </DataGrid>
    

    但恐怕,这不是您所追求的完整解决方案,因为如果网格失去焦点,所选项目将失去突出显示。

    因此,如果您希望在网格失去焦点后也突出显示该选择,您应该重写 DataGridRow 控件模板,即视觉样式“UnfocusedSelected”。

    【讨论】:

      猜你喜欢
      • 2011-03-31
      • 2021-11-28
      • 2016-11-15
      • 2013-08-08
      • 1970-01-01
      • 2013-12-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多