web-dev-qa-db-fra.com

Liaison de texte d'en-tête de grille de données WPF

L'en-tête de colonne du DataGrid n'est pas un élément FrameWork pour une raison quelconque, et vous ne pouvez donc pas utiliser de liaisons pour définir des éléments tels que le texte d'en-tête. Veuillez me corriger si c'est faux ou si cela a changé avec .NET 4.0 (j'utilise le dernier WPFToolkit de CodePlex maintenant).

J'essaie d'utiliser le DataGrid pour une présentation de feuille de temps où la date du jour doit faire partie du texte d'en-tête (c.-à-d. "Dim 01 nov"), et j'ai ce qui suit dans mon XAML:

        <dg:DataGrid.Columns>
        <dg:DataGridTextColumn Header="Description" Width="Auto" Binding="{Binding Description}" IsReadOnly="True"/>
        <dg:DataGridTextColumn Header="Mon" Width="50" Binding="{Binding Allocations[0].Amount}"  />
... every other day of the week ....
        <dg:DataGridTextColumn Header="Sun" Width="50" Binding="{Binding Allocations[6].Amount}"  />
        <dg:DataGridTextColumn Header="Total" MinWidth="50" Binding="{Binding TotalAllocatedAmount}" IsReadOnly="True" />
    </dg:DataGrid.Columns>

Je voudrais utiliser le même AllocationViewModel que j'utilise pour les données (par exemple, "{Binding Allocations [0] .Amount}" et lier sa propriété DisplayName au texte d'en-tête. Quelqu'un peut-il me montrer comment faire cela? Si j'ai pour utiliser une ressource statique, comment puis-je y insérer le DataContext?

MODIFIER ---------------- TRAVAIL PRÉFÉRÉ AUTOUR

Josh Smith avait publié environ DataContextSpy il y a quelque temps, et c'est la solution de contournement la plus propre que j'ai trouvée à ce problème. Voici la classe qui le fait fonctionner:

/// <summary>
/// Workaround to enable <see cref="DataContext"/> bindings in situations where the DataContext is not redily available. 
/// </summary>
/// <remarks>http://blogs.infragistics.com/blogs/josh_smith/archive/2008/06/26/data-binding-the-isvisible-property-of-contextualtabgroup.aspx</remarks>
public class DataContextSpy : Freezable
{
    public DataContextSpy()
    {
        // This binding allows the spy to inherit a DataContext.
        BindingOperations.SetBinding(this, DataContextProperty, new Binding());
    }

    public object DataContext
    {
        get { return GetValue(DataContextProperty); }
        set { SetValue(DataContextProperty, value); }
    }

    // Borrow the DataContext dependency property from FrameworkElement.
    public static readonly DependencyProperty DataContextProperty = FrameworkElement
        .DataContextProperty.AddOwner(typeof (DataContextSpy));

    protected override Freezable CreateInstanceCore()
    {
        // We are required to override this abstract method.
        throw new NotImplementedException();
    }
}

Avec cela en place, je peux détourner le DC dont j'ai besoin dans xaml:

    <dg:DataGrid.Resources>
        <behavior:DataContextSpy x:Key="spy" DataContext="{Binding Allocations}" />
    </dg:DataGrid.Resources>

Et puis appliquez au besoin via la liaison:

            <dg:DataGridTextColumn Header="{Binding Source={StaticResource spy}, Path=DataContext[0].DisplayName}" 
                               Width="50" Binding="{Binding Allocations[0].Amount}"  />

Suh-weet!

27
Berryl

C'est le moyen facile de lier l'en-tête DataGridTextColumn au contexte de données:

<DataGrid x:Name="summaryGrid" Grid.Row="3" AutoGenerateColumns="False" IsReadOnly="True" CanUserAddRows="False">
       <DataGrid.Columns>
            <DataGridTextColumn Header="Hard Coded Title" Width="*"/>
            <DataGridTextColumn Width="100">
                <DataGridTextColumn.Header>
                    <TextBlock Text="{Binding DataContext.SecondColumnTitle, 
                                              RelativeSource={RelativeSource AncestorType={x:Type local:MainWindow}}}"/>
                </DataGridTextColumn.Header>
            </DataGridTextColumn>
            <DataGridTextColumn Width="150">
                <DataGridTextColumn.Header>
                    <TextBlock Text="{Binding DataContext.ThirdColumnTitle, 
                                              RelativeSource={RelativeSource AncestorType={x:Type local:MainWindow}}}"/>
                </DataGridTextColumn.Header>
            </DataGridTextColumn>
        </DataGrid.Columns>
    </DataGrid>

Vous aurez évidemment besoin d'avoir les propriétés: SecondColumnTitle et ThirdColumnTitle implémentées sur votre classe de contexte de données.

J'ai cette solution fonctionnant dans .net 4.5 et n'ai eu aucune chance ni raison de l'essayer dans les versions antérieures du cadre.

18
mmichtch

BTW, dans Silverlight (testé avec SL 3.0), vous pouvez simplement utiliser la propriété Header comme DataContext pour le ControlTemplate défini via HeaderStyle (voir mon question connexe sur SO ).

Je viens d'essayer cette solution dans WPF 3.5 en utilisant le WPF Toolkit DataGrid et cela fonctionne !

4
Philipp Schmid

**ÉDITER :-

Vous pouvez styliser le DataGridColumnHeader et faire des liaisons funky. essayez ici et téléchargez ColumnHeaderBindings.Zip, il a un petit projet de test, c'est un peu un hack, mais ça marche

** Fin de l'édition

La liaison sur la colonne se produit sur une base par ligne , la colonne ne fait pas partie de l'arborescence visuelle, la liaison est appliquée à chaque élément de la grille, à partir du code source des grilles, vous pouvez voir que la propriété Binding a ces commentaires

    /// <summary>
    ///     The binding that will be applied to the generated element.
    /// </summary>
    /// <remarks>
    ///     This isn't a DP because if it were getting the value would evaluate the binding.
    /// </remarks>

La liaison aux colonnes n'a donc pas beaucoup de sens, car comme vous l'avez découvert, lorsque vous ne faites pas partie de l'arborescence visuelle, vous n'avez pas de contexte de données.

Le même problème existe avec le ComboBoxColumn lorsque vous souhaitez vous lier à la source des éléments. Vous pouvez vous lier à une StaticResource, mais StaticResources n'a pas non plus de contexte de données. Vous pouvez utiliser un fournisseur de données d'objet ou simplement instancier directement dans xaml.

mais je voudrais simplement créer les colonnes dans le code et définir l'en-tête. ce problème disparaîtrait alors.

il y a un bon article ici sur la disposition visuelle.

2
Aran Mulholland

Ma solution permet d'écrire une seule ligne dans DataGridColumn avec le nom de la propriété à lier. Il a les caractéristiques suivantes:

  • Il existe un support pour DataGridTextColumn
  • Il existe un support pour DataGridTemplateColumn
  • Définissez StringFormat pour chaque colonne
  • Spécifiez une valeur statique pour le StringFormat
  • Conforme entièrement au modèle MVVM

L'exemple ci-dessous inclut StringFormat (il doit se tenir devant le PropertyPath):

<DataGridTextColumn Behaviors:DataGridHeader.StringFormat="StringFormat: {0:C}"
                    Behaviors:DataGridHeader.PropertyPath="HeaderValueOne" ... /> 

Équivalent à cette ligne:

<DataGridTextColumn HeaderStringFormat="{0:C}"
                    Header="{Binding Path=HeaderValueOne}" ... />

Si vous avez besoin de plus d'exemples de solutions et de fonctionnalités, veuillez lire ci-dessous.

Link pour l'exemple de projet.


Notes about the solution

De toutes les solutions que j'ai vues plus tôt, la plus simple pour moi s'est avérée être celle-ci example :

<DataGridTextColumn Binding="{Binding Name}">
    <DataGridTextColumn.HeaderTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Path=DataContext.YourPropertyName,
                                      RelativeSource={RelativeSource AncestorType={x:Type SomeControl}}" />
         </DataTemplate>
    </DataGridTextColumn.HeaderTemplate>
</DataGridTextColumn>        

Veuillez faire attention à DataGridTextColumn.HeaderTemplate, si a été utilisé DataGridTextColumn.Header, alors pour le framework .NET inférieur à la version 4.5 et pour Silverlight produirait une exception:

La propriété d'en-tête ne prend pas en charge les UIElements

Il semblerait que ce qui est nécessaire? Je voulais trouver une solution qui permettrait d'écrire une seule ligne dans DataGridColumn avec le nom de la propriété à lier.

Et voici ce qui s'est passé:

<DataGridTextColumn Behaviors:DataGridHeader.PropertyPath="HeaderValueOne" // Attached dependency property 

Cette construction similaire à celle-ci:

<DataGridTextColumn Header="{Binding Path=HeaderValueOne}" ... />

Il est également possible d'utiliser StringFormat pour chaque colonne comme ceci:

<DataGridTextColumn Behaviors:DataGridHeader.StringFormat="StringFormat: {0:C}"
                    Behaviors:DataGridHeader.PropertyPath="TestStringFormatValue" ... />

Et il y a la possibilité de spécifier une valeur statique pour le StringFormat:

<DataGridTextColumn Behaviors:DataGridHeader.StringFormat="{x:Static Member=this:TestData.TestStaticStringFormatValue}" // public static string TestStaticStringFormatValue = "Static StringFormat: {0}$";
                    Behaviors:DataGridHeader.PropertyPath="TestStringFormatValue"

Voici l'original DataTemplate, qui est défini dynamiquement sur la colonne:

<DataTemplate>
    <TextBlock Text="{Binding Path=DataContext.YourPropertyName,
                              StringFormat="YourStringFormat",
                              RelativeSource={RelativeSource AncestorType={x:Type DataGridCellsPanel}}}" />
</DataTemplate>

Afin de RelativeSource ne dépendait pas du type de DataContext, j'ai pris grand solution de Mr . Bruno .

Dans ce cas, DataGridCellsPanel contient le DataContext correct, qui est défini pour un DataGrid parent.

Voici le code de base qui est effectué toute la magie:

IsSetHeader PropertyChanged handler

private static void IsSetHeader(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
    var textColumn = sender as DataGridTextColumn;
    var templateColumn = sender as DataGridTemplateColumn;
    string path = e.NewValue as string;

    if ((textColumn == null) & (templateColumn == null)) 
    {
        return;
    }

    if (String.IsNullOrEmpty(path) == false)
    {
        currentStringFormat = ReturnStringFormat(textColumn, templateColumn);
        dataTemplate = CreateDynamicDataTemplate(path, currentStringFormat);

        if (dataTemplate != null)
        {
            if (textColumn != null)
                textColumn.HeaderTemplate = dataTemplate;

            if (templateColumn != null)
                templateColumn.HeaderTemplate = dataTemplate;
        }
    }
}

CreateDynamicDataTemplate

private static DataTemplate CreateDynamicDataTemplate(string propertyPath, string stringFormat)
{
    var pc = new ParserContext();
    MemoryStream sr = null;

    string xaml = GetXamlString(propertyPath, stringFormat);            
    sr = new MemoryStream(Encoding.ASCII.GetBytes(xaml));

    pc.XmlnsDictionary.Add("", "http://schemas.Microsoft.com/winfx/2006/xaml/presentation");
    pc.XmlnsDictionary.Add("x", "http://schemas.Microsoft.com/winfx/2006/xaml");

    return XamlReader.Load(sr, pc) as DataTemplate;
}

GetXamlString

private static string GetXamlString(string propertyPath, string stringFormat)
{
    #region Original PropertyPath for TextBlock

    // {Binding Path=DataContext.YourProperty, RelativeSource={RelativeSource AncestorType={x:Type DataGridCellsPanel}}}"
    // Thanks to Bruno (https://stackoverflow.com/users/248118/bruno) for this trick

    #endregion

    var sb = new StringBuilder();

    sb.Append("<DataTemplate><TextBlock Text=\"{Binding Path=DataContext.");
    sb.Append(propertyPath);
    sb.Append(", StringFormat=");
    sb.Append(stringFormat);
    sb.Append(", RelativeSource={RelativeSource AncestorType={x:Type DataGridCellsPanel}}}\" /></DataTemplate>");

    return sb.ToString();
}

StringFormat doit apparaître avant le PropertyPath, car il est facultatif. Pour que les colonnes, qui ne l'ont pas, ce ne soit pas une exception, j'ai enregistré try-catch dans GetStringFormat:

 public static string GetStringFormat(DependencyObject DepObject)
 {
    try
    {
        return (string)DepObject.GetValue(StringFormatProperty);
    }

    catch 
    {
        return String.Empty;
    }
 }

Plus: n'écrivez pas dans les méthodes try-catch block, qui tentent d'obtenir la valeur.

Moins: Le moins pour chaque exception StringFormat manquée sera généré une fois au démarrage du programme. Si cela est essentiel pour vous, vous pouvez toujours spécifier le StringFormat="null" pour la colonne.

Au cas où, montrez le code complet du projet:

public static class DataGridHeader
{
    #region Private Section

    private static string textColumnStringFormat = null;
    private static string templateColumnStringFormat = null;
    private static string currentStringFormat = null;
    private static DataTemplate dataTemplate = null;

    #endregion

    #region PropertyPath DependencyProperty

    public static readonly DependencyProperty PropertyPathProperty;

    public static void SetPropertyPath(DependencyObject DepObject, string value)
    {
        DepObject.SetValue(PropertyPathProperty, value);
    }

    public static string GetPropertyPath(DependencyObject DepObject)
    {
        return (string)DepObject.GetValue(PropertyPathProperty);
    }

    #endregion

    #region StringFormat DependencyProperty

    public static readonly DependencyProperty StringFormatProperty;

    public static void SetStringFormat(DependencyObject DepObject, string value)
    {
        DepObject.SetValue(StringFormatProperty, value);
    }

    public static string GetStringFormat(DependencyObject DepObject)
    {
        try
        {
            return (string)DepObject.GetValue(StringFormatProperty);
        }

        catch 
        {
            return String.Empty;
        }
    }

    #endregion

    #region Constructor

    static DataGridHeader()
    {
        PropertyPathProperty = DependencyProperty.RegisterAttached("PropertyPath",
                                                                   typeof(string),
                                                                   typeof(DataGridHeader),
                                                                   new UIPropertyMetadata(String.Empty, IsSetHeader));

        StringFormatProperty = DependencyProperty.RegisterAttached("StringFormat",
                                                                   typeof(string),
                                                                   typeof(DataGridHeader),
                                                                   new UIPropertyMetadata(String.Empty));  
    }

    #endregion

    #region IsSetHeader PropertyChanged Handler

    private static void IsSetHeader(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {
        var textColumn = sender as DataGridTextColumn;
        var templateColumn = sender as DataGridTemplateColumn;
        string path = e.NewValue as string;

        if ((textColumn == null) & (templateColumn == null)) 
        {
            return;
        }

        if (String.IsNullOrEmpty(path) == false)
        {
            currentStringFormat = ReturnStringFormat(textColumn, templateColumn);
            dataTemplate = CreateDynamicDataTemplate(path, currentStringFormat);

            if (dataTemplate != null)
            {
                if (textColumn != null)
                    textColumn.HeaderTemplate = dataTemplate;

                if (templateColumn != null)
                    templateColumn.HeaderTemplate = dataTemplate;
            }
        }
    }

    #endregion

    #region ReturnStringFormat Helper

    private static string ReturnStringFormat(DependencyObject depObject1, DependencyObject depObject2) 
    {
        textColumnStringFormat = GetStringFormat(depObject1) as string;
        templateColumnStringFormat = GetStringFormat(depObject2) as string;

        if (String.IsNullOrEmpty(textColumnStringFormat) == false)
        {
            return textColumnStringFormat;
        }

        if (String.IsNullOrEmpty(templateColumnStringFormat) == false)
        {
            return templateColumnStringFormat;
        }

        return "null";
    }

    #endregion

    #region CreateDynamicDataTemplate Helper

    private static DataTemplate CreateDynamicDataTemplate(string propertyPath, string stringFormat)
    {
        var pc = new ParserContext();
        MemoryStream sr = null;

        string xaml = GetXamlString(propertyPath, stringFormat);            
        sr = new MemoryStream(Encoding.ASCII.GetBytes(xaml));

        pc.XmlnsDictionary.Add("", "http://schemas.Microsoft.com/winfx/2006/xaml/presentation");
        pc.XmlnsDictionary.Add("x", "http://schemas.Microsoft.com/winfx/2006/xaml");

        return XamlReader.Load(sr, pc) as DataTemplate;
    }

    #endregion

    #region GetXamlString Helper

    private static string GetXamlString(string propertyPath, string stringFormat)
    {
        #region Original PropertyPath for TextBlock

        // {Binding Path=DataContext.YourProperty, RelativeSource={RelativeSource AncestorType={x:Type DataGridCellsPanel}}}"
        // Thanks to Bruno (https://stackoverflow.com/users/248118/bruno) for this trick

        #endregion

        var sb = new StringBuilder();

        sb.Append("<DataTemplate><TextBlock Text=\"{Binding Path=DataContext.");
        sb.Append(propertyPath);
        sb.Append(", StringFormat=");
        sb.Append(stringFormat);
        sb.Append(", RelativeSource={RelativeSource AncestorType={x:Type DataGridCellsPanel}}}\" /></DataTemplate>");

        return sb.ToString();
    }

    #endregion
}

XAML

<Window x:Class="BindingHeaderInDataGrid.MainWindow"
        xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
        xmlns:this="clr-namespace:BindingHeaderInDataGrid"
        xmlns:Behaviors="clr-namespace:BindingHeaderInDataGrid.AttachedBehaviors"
        WindowStartupLocation="CenterScreen"
        Title="MainWindow" Height="220" Width="600">

    <Window.DataContext>
        <this:TestData />
    </Window.DataContext>

    <Grid Name="TestGrid">
        <DataGrid Name="TestDataGrid" 
                  Width="550"
                  Height="100"
                  Margin="10"
                  VerticalAlignment="Top"
                  Background="AliceBlue">

            <DataGrid.Columns>
                <DataGridTextColumn Behaviors:DataGridHeader.StringFormat="StringFormat: {0:C}"
                                    Behaviors:DataGridHeader.PropertyPath="TestStringFormatValue"
                                    Width="100"
                                    IsReadOnly="False">

                    <DataGridTextColumn.HeaderStyle>
                        <Style TargetType="{x:Type DataGridColumnHeader}">
                            <Setter Property="Height" Value="20" />
                            <Setter Property="Background" Value="Pink" />
                            <Setter Property="Margin" Value="2,0,0,0" />
                        </Style>
                    </DataGridTextColumn.HeaderStyle>
                </DataGridTextColumn>

                <DataGridTextColumn Behaviors:DataGridHeader.StringFormat="{x:Static Member=this:TestData.TestStaticStringFormatValue}"
                                    Behaviors:DataGridHeader.PropertyPath="TestStringFormatValue"
                                    Width="2*"
                                    IsReadOnly="False">

                    <DataGridTextColumn.HeaderStyle>
                        <Style TargetType="{x:Type DataGridColumnHeader}">
                            <Setter Property="Height" Value="20" />
                            <Setter Property="Background" Value="CadetBlue" />
                            <Setter Property="Margin" Value="2,0,0,0" />
                        </Style>
                    </DataGridTextColumn.HeaderStyle>
                </DataGridTextColumn>

                <DataGridTextColumn Behaviors:DataGridHeader.PropertyPath="TestUsualHeaderValue"
                                    Width="1.5*" 
                                    IsReadOnly="False">

                    <DataGridTextColumn.HeaderStyle>
                        <Style TargetType="{x:Type DataGridColumnHeader}">
                            <Setter Property="Height" Value="20" />
                            <Setter Property="Background" Value="Gainsboro" />
                            <Setter Property="Margin" Value="2,0,0,0" />
                        </Style>
                    </DataGridTextColumn.HeaderStyle>
                </DataGridTextColumn>

                <DataGridTemplateColumn Behaviors:DataGridHeader.PropertyPath="TestTemplateColumnValue"
                                        Width="150"
                                        IsReadOnly="False">

                    <DataGridTemplateColumn.HeaderStyle>
                        <Style TargetType="{x:Type DataGridColumnHeader}">
                            <Setter Property="Height" Value="20" />
                            <Setter Property="Background" Value="Beige" />
                            <Setter Property="Margin" Value="2,0,0,0" />
                        </Style>
                    </DataGridTemplateColumn.HeaderStyle>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>

        <Button Name="ChangeHeader" 
                Width="100" 
                Height="30"
                VerticalAlignment="Bottom"
                Content="ChangeHeader" 
                Click="ChangeHeader_Click" />
    </Grid>
</Window>

Code-behind

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }        

    private void ChangeHeader_Click(object sender, RoutedEventArgs e)
    {
        TestData data = this.DataContext as TestData;

        data.TestStringFormatValue = "777";
        data.TestUsualHeaderValue = "DynamicUsualHeader";
        data.TestTemplateColumnValue = "DynamicTemplateColumn";
    }
}

public class TestData : NotificationObject
{
    #region TestStringFormatValue

    private string _testStringFormatValue = "1";

    public string TestStringFormatValue
    {
        get
        {
            return _testStringFormatValue;
        }

        set
        {
            _testStringFormatValue = value;
            NotifyPropertyChanged("TestStringFormatValue");
        }
    }

    #endregion

    #region TestStaticStringFormatValue

    public static string TestStaticStringFormatValue = "Static StringFormat: {0}$";

    #endregion

    #region TestUsualHeaderValue

    private string _testUsualHeaderValue = "UsualHeader";

    public string TestUsualHeaderValue
    {
        get
        {
            return _testUsualHeaderValue;
        }

        set
        {
            _testUsualHeaderValue = value;
            NotifyPropertyChanged("TestUsualHeaderValue");
        }
    }

    #endregion

    #region TestTemplateColumnValue

    private string _testTemplateColumnValue = "TemplateColumn";

    public string TestTemplateColumnValue
    {
        get
        {
            return _testTemplateColumnValue;
        }

        set
        {
            _testTemplateColumnValue = value;
            NotifyPropertyChanged("TestTemplateColumnValue");
        }
    }

    #endregion
}
2
Anatoliy Nikolaev

Je sais que ce message est ancien, mais quand j'ai cherché comment faire, c'est la première entrée qui est apparue. Je n'ai pas aimé cette réponse car elle semblait exagérée. Après plus de recherches, je suis tombé sur ce lien le montre comment faire cela dans le balisage, en utilisant une colonne de modèle.

<DataGridTemplateColumn>
    <DataGridTemplateColumn.HeaderTemplate>
        <DataTemplate>
            **<TextBlock Text="{Binding DataContext.HeaderTitle, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" />**
        </DataTemplate>
    </DataGridTemplateColumn.HeaderTemplate>
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding}" Width="200" />
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
1
Mike Collins

La réponse de @ mmichtch fonctionne bien pour moi, il vous suffit de créer un espace de noms local (xmlns), qui contient la référence à votre projet comme suit:

xmlns:local="clr-namespace:your_project_name"

et en même temps n'oubliez pas de mentionner la propriété que vous souhaitez lier:

                <DataGridTextColumn Width="Auto">
                <DataGridTextColumn.Header>
                    <TextBlock Text="{Binding DataContext.PropertyNameYouWantToBind, 
                                          RelativeSource={RelativeSource AncestorType={x:Type local:MainWindow}}}"/>
                </DataGridTextColumn.Header>
            </DataGridTextColumn>

il fonctionne bien avec VS 2010 et .net version 4.

1
Sabeen

J'ai résolu cela en utilisant le HeaderTemplate et en me liant au DataContext du DataGrid, en utilisant RelativeSource.

<DataGrid ItemsSource="{Binding Items}">
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding Value1}">
            <DataGridTextColumn.HeaderTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding DataContext.ColumnTitel1, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/>
                </DataTemplate>
            </DataGridTextColumn.HeaderTemplate>
        </DataGridTextColumn>
    </DataGrid.Columns>
</DataGrid>

La même liaison dans la propriété Header n'a pas fonctionné.

1
Heiner

une solution encore meilleure serait de définir la liaison dans le style de l'en-tête et de passer la colonne comme dataContext de l'en-tête ... (ou encore mieux: de configurer un objet représentant le dataContext de l'en-tête et de le passer)

voyez là pour un moyen de le faire:

Comment définir le DataContext sur un en-tête de colonne DataGrid

1
David

Je l'ai utilisé pour remplir l'en-tête de colonne DataGrid.

<DataGridTextColumn Binding="{Binding RowData}" Header="{Binding Mode=OneWay, Source={StaticResource spy},Path=DataContext.HeaderText,  FallbackValue= header text}"/>

J'ai utilisé une valeur de secours en minuscules et la valeur de DataContext a été capitalisée pour m'assurer que la ressource n'était pas nulle. De plus, la valeur de DataContext n'apparaissait pour moi qu'au moment de l'exécution, pendant la conception, elle affichait la valeur de secours. J'espère que cela t'aides.

0
taysoren