2011-03-04 90 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);