WPF декомпозиция - DataGridTemplateColumn

Я пытаюсь переместить пользовательское определение столбца DataGrid в UserControl.

MyComboBoxColumn.xaml

<dg:DataGridTemplateColumn 
    x:Class="WpfDecomposition.MyComboBoxColumn"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:dg="clr-namespace:Microsoft.Windows.Controls;assembly=WpfToolkit"
    x:Name="_this"
    >

    <dg:DataGridTemplateColumn.Header>
        <Button Content="{Binding MyHeader, ElementName=_this}" ></Button>
    </dg:DataGridTemplateColumn.Header>

</dg:DataGridTemplateColumn>

MyComboBoxColumn.cs

public partial class MyComboBoxColumn : DataGridTemplateColumn
{
    public MyComboBoxColumn()
    {
        InitializeComponent();
    }

    public static DependencyProperty MyHeaderProperty = 
        DependencyProperty.Register("MyHeader", typeof(string), typeof(MyComboBoxColumn), new PropertyMetadata("TEST"));
}

Основные окна XAML:

<dg:DataGrid CanUserAddRows="True" AutoGenerateColumns="False">
    <dg:DataGrid.Columns>
        <my:MyComboBoxColumn />
    </dg:DataGrid.Columns>
</dg:DataGrid>

Я ожидаю увидеть кнопку "ТЕСТ" в заголовке столбца, но вместо этого я вижу пустую кнопку. Похоже, переплет сломан. Что случилось?

2 ответа

Решение

Это не работает, потому что не может найти элемент с именем _this, Я получаю следующую ошибку в окне вывода при отладке кода в Visual Studio:

System.Windows.Data Ошибка: 4: не удается найти источник для привязки со ссылкой "ElementName=_this". BindingExpression:Path=MYHEADER; DataItem= NULL; Целевым элементом является "Кнопка" (Name='TestButton'); Целевым свойством является "Содержимое" (тип "Объект").

Что касается того, почему это не может найти это - я думаю, что это потому, что привязки WPF используют визуальное дерево, чтобы найти источник привязки. В этом случае MyComboBoxColumn отсутствует в визуальном дереве, поэтому он не может найти элемент с таким именем.

Я также пытался использовать RelativeSource чтобы найти элемент, но это тоже не сработало - вероятно, по той же причине.

Единственное, что я мог получить на работу, это установить DataContext кнопки для самого столбца в конструкторе:

public MyComboBoxColumn()
{
    InitializeComponent();

    this.TestButton.DataContext = this;
}

А затем измените привязку в XAML:

<tk:DataGridTemplateColumn.Header>
    <Button Content="{Binding Path=MyHeader}" x:Name="TestButton" />
</tk:DataGridTemplateColumn.Header>

Это не лучший способ сделать это, но, по крайней мере, это работает.

Если вы не хотите или не можете установить DataContext в конструкторе (например, при динамическом создании столбцов в коде), установите столбец Header свойство объекта, с которым вы хотите связать (контекст данных), а затем вы можете связать с этим объектом в HeaderStyle шаблон данных.

Смотрите этот вопрос для деталей.

Другие вопросы по тегам