2017-04-10 4 views
0

Je suis juste en train d'essayer de définir le Background de mon DataGridTemplateColumn.Header avec un Binding à un DependencyProperty personnalisé. Je peux le définir explicitement pour une couleur dans le style, mais j'en ai besoin pour changer en fonction de certaines préférences de l'utilisateur. Je ne veux pas avoir à écrire du code pour déterrer et trouver chacun des en-têtes dans chacune des grilles dans chacune de mes vues.Liaison ne fonctionne pas dans ColumnHeaderStyle de DataGrid

Je suis sûr qu'il me manque quelque chose de très simple, comme si je ne définissais pas le DataContext correctement, mais j'ai essayé tout ce qui me vient à l'esprit, et rien n'a fonctionné. Je n'ai jamais utilisé un DataGrid auparavant, alors j'essaie toujours de comprendre beaucoup de choses. Quelqu'un s'il vous plaît dites-moi ce que je manque.

XAML:

<Window x:Class="DataGridTest.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:local="clr-namespace:DataGridTest" 
     mc:Ignorable="d" 
     Title="Data Grid Test" Height="300" Width="525" 
     WindowStartupLocation="CenterScreen"> 
    <DataGrid Name="DataGrid1" 
       AutoGenerateColumns="False" 
       MaxWidth="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}, Path=Width}" 
       ScrollViewer.CanContentScroll="False"> 
     <DataGrid.ColumnHeaderStyle> 
      <Style TargetType="{x:Type DataGridColumnHeader}"> 
       <Setter Property="HorizontalAlignment" Value="Stretch" /> 
       <Setter Property="HorizontalContentAlignment" Value="Center" /> 
       <Setter Property="Background" Value="{Binding HeaderBackground}" /> 
      </Style> 
     </DataGrid.ColumnHeaderStyle> 
     <DataGrid.Columns> 
      <DataGridTemplateColumn IsReadOnly="True" Width="*"> 
       <DataGridTemplateColumn.Header> 
        <ComboBox Name="CB1"> 
         <ComboBoxItem Name="CBI11" Content="Choose..." IsSelected="True" /> 
         <ComboBoxItem Name="CBI12" Content="First Choice" /> 
         <ComboBoxItem Name="CBI13" Content="Second Choice" /> 
        </ComboBox> 
       </DataGridTemplateColumn.Header> 
       <DataGridTemplateColumn.CellTemplate> 
        <DataTemplate> 
         <Label Content="{Binding Text1}" /> 
        </DataTemplate> 
       </DataGridTemplateColumn.CellTemplate> 
      </DataGridTemplateColumn> 

      <DataGridTemplateColumn IsReadOnly="True" Width="Auto"> 
       <DataGridTemplateColumn.Header> 
        <ComboBox Name="CB2"> 
         <ComboBoxItem Name="CBI21" Content="Choose..." IsSelected="True" /> 
         <ComboBoxItem Name="CBI22" Content="First Choice" /> 
         <ComboBoxItem Name="CBI23" Content="Second Choice" /> 
        </ComboBox> 
       </DataGridTemplateColumn.Header> 
       <DataGridTemplateColumn.CellTemplate> 
        <DataTemplate> 
         <Label Content="{Binding Text2}" /> 
        </DataTemplate> 
       </DataGridTemplateColumn.CellTemplate> 
      </DataGridTemplateColumn> 
     </DataGrid.Columns> 
    </DataGrid> 
</Window> 

C#:

using System.Collections.ObjectModel; 
using System.ComponentModel; 
using System.Windows; 
using System.Windows.Documents; 
using System.Windows.Media; 

namespace DataGridTest 
{ 
    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 
      DataContext = this; 
      DataGrid1.ItemsSource = TestClass.GetTestText(); 

      HeaderBackground = (Brush)new BrushConverter().ConvertFromString("#FF0000FF"); 
     } 

     public Brush HeaderBackground 
     { 
      get { return (Brush)GetValue(HeaderBackgroundProperty); } 
      set 
      { 
       SetValue(HeaderBackgroundProperty, value); 
       RaisePropertyChanged("HeaderBackgroundProperty"); 
      } 
     } 
     private static readonly DependencyProperty HeaderBackgroundProperty = 
      DependencyProperty.Register("HeaderBackground", typeof(Brush), typeof(MainWindow), new PropertyMetadata((Brush)new BrushConverter().ConvertFromString("#FFFF0000"))); 

     public event PropertyChangedEventHandler PropertyChanged; 
     private void RaisePropertyChanged(string caller = "") 
     { 
      if (PropertyChanged != null) 
      { 
       PropertyChanged(this, new PropertyChangedEventArgs(caller)); 
      } 
     } 
    } 

    internal class TestClass : INotifyPropertyChanged 
    { 
     private Span text1; 
     public Span Text1 
     { 
      get { return text1; } 
      set 
      { 
       text1 = value; 
       RaisePropertyChanged(); 
      } 
     } 

     private Span text2; 
     public Span Text2 
     { 
      get { return text2; } 
      set 
      { 
       text2 = value; 
       RaisePropertyChanged(); 
      } 
     } 

     public static ObservableCollection<TestClass> GetTestText() 
     { 
      ObservableCollection<TestClass> TestList = new ObservableCollection<TestClass>(); 
      for (int i = 0; i < 10; i++) 
      { 
       Run run1 = new Run("This is a test. "); 
       Hyperlink link1 = new Hyperlink(new Run("This is only a test.")); 
       Span span1 = new Span(); 
       span1.Inlines.AddRange(new Inline[] { run1, link1 }); 

       Run run2 = new Run("If this was not a test, "); 
       Hyperlink link2 = new Hyperlink(new Run("something would be happening.")); 
       Span span2 = new Span(); 
       span2.Inlines.AddRange(new Inline[] { run2, link2 }); 

       TestList.Add(new TestClass() { Text1 = span1, Text2 = span2 }); 
      } 
      return TestList; 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 
     private void RaisePropertyChanged(string caller = "") 
     { 
      if (PropertyChanged != null) 
      { 
       PropertyChanged(this, new PropertyChangedEventArgs(caller)); 
      } 
     } 
    } 
} 

Répondre

1

Vous pouvez simplement spécifier un RelativeSource de la liaison:

<DataGrid.ColumnHeaderStyle> 
    <Style TargetType="{x:Type DataGridColumnHeader}"> 
     <Setter Property="HorizontalAlignment" Value="Stretch" /> 
     <Setter Property="HorizontalContentAlignment" Value="Center" /> 
     <Setter Property="Background" Value="{Binding HeaderBackground, RelativeSource={RelativeSource AncestorType=Window}}" /> 
    </Style> 
</DataGrid.ColumnHeaderStyle> 

Le DataContext du DataGridColumnHeader n'est pas la fenêtre et c'est la raison pour laquelle votre liaison d'origine ne fonctionne pas.

Vous pouvez utiliser un RelativeSource pour lier à une propriété d'un élément parent dans l'arborescence visuelle, comme par exemple la fenêtre parent.

+0

Voyez, je savais que ce serait super simple. Merci! Fait intéressant, j'ai également réussi à obtenir le résultat souhaité en définissant explicitement 'BorderBrush'. Je ne comprends pas pourquoi, mais pour une raison quelconque quand je l'ai fait, la liaison d'origine (sans la source relative) a fonctionné. – Meloviz

1

Donnez un nom à votre fenêtre principale. par exemple. x:Name="MyWindow"

Vous avez créé la propriété de dépendance "HeaderBackground" pour la fenêtre principale. Donc, pour y accéder, vous devez utiliser la liaison ElementName.

<DataGrid.ColumnHeaderStyle> 
     <Style TargetType="{x:Type DataGridColumnHeader}"> 
      <Setter Property="HorizontalAlignment" Value="Stretch" /> 
      <Setter Property="HorizontalContentAlignment" Value="Center" /> 
      <Setter Property="Background" Value="{Binding ElementName=MyWindow, Path=HeaderBackground}" /> 
     </Style> 
</DataGrid.ColumnHeaderStyle> 

enter image description here

Hope this helps.

+0

Merci, @Parag. Votre réponse a donné le résultat escompté, mais j'ai choisi de ne pas faire de la vôtre la réponse acceptée parce que je n'aime pas x: nommer des choses si je n'en ai pas besoin. C'est une autre façon qui fonctionne, cependant, je l'apprécie. +1 – Meloviz