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
шаблон данных.
Смотрите этот вопрос для деталей.