2011-03-04 78 views
6

我有一个WPF的Datagrid绑定某些属性,在我的ViewModelWPF Datagrid的:在负载,选择对目前的项目(高亮)

<DataGrid AutoGenerateColumns="False" Name="dataGrid" SelectionMode="Single" 
      ItemsSource="{Binding ItemList}" SelectedItem="{Binding SelectedItem}"> 
... 
</DataGrid> 

当我的窗口负载和数据网格太,我设置了SelectedItem它绑定很好,但行没有突出显示。当我点击一行时,行突出显示并解决问题。

如何在加载/初始化时在DataGrid中设置/触发SelectedItem的突出显示?

编辑:

它的实际选择,因为我有一点选择单元格。这只是突出显示的渲染不会触发。

enter image description here

回答

7

当使用型号为DataContext的一个WPF窗口,DataGrid的SelectionChanged事件不会被调用后窗口加载这就是为什么该行从来没有突出显示,你只能看到第一个,直到与部分重点排。可能有更优雅的方式,但这里有一个解决方法。

在窗口的加载事件或DataGrid的加载事件,重置的SelectedItem绑定:

public MainWindow() 
{ 
    InitializeComponent(); 
    this.Loaded += new RoutedEventHandler(OnLoaded); 
} 

// could also be placed in the DataGrid's loaded event handler 
private void OnLoaded(object sender, RoutedEventArgs e) 
{ 
    if(dataGrid != null && Model.SelectedItem != null) 
    { 
     var selected = Model.SelectedItem; 
     Model.SelectedItem = null; 
     Model.SelectedItem = selected; 
    } 
} 

下面是一个完整的工作样本。

XAML

<Window x:Class="WpfDataGridHighlightOnLoad.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:model="clr-namespace:WpfDataGridHighlightOnLoad" 
     Title="MainWindow" Height="350" Width="525"> 

    <Window.DataContext> 
     <model:MainWindowModel x:Name="Model" /> 
    </Window.DataContext> 

    <Grid> 
     <DataGrid AutoGenerateColumns="True" SelectionMode="Single" 
        HorizontalAlignment="Stretch" 
        Name="dataGrid" 
        VerticalAlignment="Top" 
        ItemsSource="{Binding ItemList}" 
        SelectedItem="{Binding SelectedItem}"> 
     </DataGrid> 

     <Button Content="Cycle Selection" Click="OnCycleClick" 
       Height="23" 
       HorizontalAlignment="Right" 
       Name="button1" 
       VerticalAlignment="Bottom" Width="125" /> 

     <Button Content="Reset Grid" Click="OnResetClick" 
       Height="23" 
       HorizontalAlignment="Left" 
       Name="button2" 
       VerticalAlignment="Bottom" Width="125" /> 

    </Grid> 
</Window> 

代码隐藏

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Windows; 

namespace WpfDataGridHighlightOnLoad 
{ 
    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 
      this.Loaded += new RoutedEventHandler(OnLoaded); 
     } 

     // could also be placed in the DataGrid's loaded event handler 
     private void OnLoaded(object sender, RoutedEventArgs e) 
     { 
      if(dataGrid != null && Model.SelectedItem != null) 
      { 
       var selected = Model.SelectedItem; 
       Model.SelectedItem = null; 
       Model.SelectedItem = selected; 
      } 
     } 

     private void OnCycleClick(object sender, RoutedEventArgs e) 
     { 
      int index = Model.ItemList.IndexOf(Model.SelectedItem); 
      index = index == Model.ItemList.Count - 1 ? 0 : index + 1; 
      Model.SelectedItem = Model.ItemList[index]; 
     } 

     private void OnResetClick(object sender, RoutedEventArgs e) 
     { 
      Model.Reset(); 
     } 
    } 

    public class MainWindowModel : INotifyPropertyChanged 
    { 
     public MainWindowModel() 
     { 
      Reset(); 
     } 

     public void Reset() 
     { 
      ItemList = new List<Person> 
          { 
           new Person("Joe", 20), 
           new Person("John", 30), 
           new Person("Jane", 40), 
           new Person("Jill", 50), 
           new Person("Fido", 7), 
          }; 

      SelectedItem = ItemList[2]; 
     } 

     private Person _selectedItem; 
     public Person SelectedItem 
     { 
      get { return _selectedItem; } 
      set 
      { 
       _selectedItem = value; 
       NotifyPropertyChanged("SelectedItem"); 
      } 
     } 

     private List<Person> _itemList; 
     public List<Person> ItemList 
     { 
      get { return _itemList; } 
      set 
      { 
       _itemList = value; 
       NotifyPropertyChanged("ItemList"); 
      } 
     } 

     #region INotifyPropertyChanged Members 

     public event PropertyChangedEventHandler PropertyChanged; 

     private void NotifyPropertyChanged(String info) 
     { 
      if(PropertyChanged != null) 
      { 
       PropertyChanged(this, new PropertyChangedEventArgs(info)); 
      } 
     } 

     #endregion 
    } 

    public class Person 
    { 
     public string Name { get; set; } 
     public int Age { get; set; } 

     public Person(string name, int age) 
     { 
      Name = name; 
      Age = age; 
     } 

     public override string ToString() 
     { 
      return Name; 
     } 
    } 
} 
+0

没有''上UIElement' – 2011-03-08 15:07:12

+1

Loaded'事件'DataGrid'从'Controls'这确实有一个'Loaded'事件继承// msdn.microsoft.com/en-us/library/system.windows.controls.datagrid_events.aspx) – 2011-03-08 15:41:12

+0

@Smurf - 重置SelecteItem已经解决了我一直试图了解的问题几天。谢谢!!! – GilShalit 2011-08-30 18:23:55

6

我有同样的 “问题”,终于找到了一个很好的解决问题的办法。正如你已经说过的那样,行并没有被选中,但它并没有突出显示该行。如果仔细观察,您会注意到,当您单击该行中的任何位置时(使用鼠标),它仍然不会突出显示该行,只会显示该行中的单元格。

所以2选项;

  • 创建代码以选择该行
  • 的细胞或创建Style.Trigger以突出显示该行(这是在我心中的最佳选择)。

要做到这一点,在XAML文件添加像这样到DataGrid:

  <DataGrid.RowStyle> 
       <Style TargetType="DataGridRow"> 
        <Style.Triggers> 
         <Trigger Property="IsSelected" Value="True"> 
          <Setter Property="Background" Value="DodgerBlue"/> 
          <Setter Property="Foreground" Value="White"/> 
         </Trigger> 
        </Style.Triggers> 
       </Style> 
      </DataGrid.RowStyle> 

希望它能帮助!

干杯, LTB

0

这是一个有点老之一,但没有任何职位的答案似乎得到它完全正确。你想要的是它按照它应该工作的方式工作:即无论控件是否有焦点(这似乎是偶然的),突出显示都是一样的。

这可以用DataGridRow风格完成,但诀窍不是自己指定颜色,而是使用默认颜色,所以一切正常。一个额外的烦恼来自于一个事实,即它是获得突出的单元格,而不是行,所以你基本上需要复制的单元格高亮风格:

<Style 
    x:Key="DataGridRowStyle" 
    TargetType="{x:Type DataGridRow}"> 
    <Style.Triggers> 
     <MultiTrigger> 
      <MultiTrigger.Conditions> 
       <Condition 
        Property="IsKeyboardFocusWithin" 
        Value="False" /> 
       <Condition 
        Property="IsSelected" 
        Value="True" /> 
      </MultiTrigger.Conditions> 
      <Setter 
       Property="Background" 
       Value="{DynamicResource 
        {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}" /> 
      <Setter 
       Property="Foreground" 
       Value="{DynamicResource 
        {x:Static SystemColors.InactiveSelectionHighlightTextBrushKey}}" /> 
     </MultiTrigger> 
     <MultiTrigger> 
      <MultiTrigger.Conditions> 
       <Condition 
        Property="IsKeyboardFocusWithin" 
        Value="True" /> 
       <Condition 
        Property="IsSelected" 
        Value="True" /> 
      </MultiTrigger.Conditions> 
      <Setter 
       Property="Background" 
       Value="{DynamicResource 
        {x:Static SystemColors.HighlightBrushKey}}" /> 
      <Setter 
       Property="Foreground" 
       Value="{DynamicResource 
        {x:Static SystemColors.HighlightTextBrushKey}}" /> 
     </MultiTrigger> 
    </Style.Triggers> 
</Style> 

注有一种疑难杂症,是设置行背景菜单中,您需要覆盖DataGrid上的DataGridRow样式,因此如果您在全局范围内执行此操作并且无法正常工作,请检查您的RowStyle尚未被覆盖。

0

当将虚拟数据插入到WPF DataGrid中时,尝试更改行顺序时,遇到同一问题。排高亮的一排排(下图)。

原因是多次插入完全相同的记录对象。 [MSDN数据网格事件](HTTP:

enter image description here

//Ex: Messes up highlighting.  
grid.Items.Add(rowObj); 
grid.Items.Add(rowObj); 
grid.Items.Add(rowObj); 

//Ex: Highlighting OK. Create a new object each time. Even if all columns have exact same values. 
rowobj = new ..... 
grid.Items.Add(rowObj); 

rowobj = new ..... 
grid.Items.Add(rowObj);