Описание: у меня есть настраиваемый элемент управления содержимым, и я пытаюсь включить некоторые внешние параметры через свойства зависимостей. По сути, это панель декоратора с двумя строками сетки, верхняя — заголовок, нижняя — содержимое (через ContentPresenter
).
Есть 3 элемента, которые привязаны к шаблону (через TemplateBinding), HeaderHeight
, TextSize
и Header
(каждый из них имеет свое свойство зависимости соответствующего типа).
Проблема. Две привязки работают идеально (даже во время разработки), а третья — нет. Привязки FontSize="{TemplateBinding TextSize}"
и Text="{TemplateBinding Header}"
работают, но <RowDefinition Height="{TemplateBinding HeaderHeight}" />
не работает.
Сетка разделяет высоту строк 50/50, независимо от того, какое значение я установил для свойства HeaderHeight. Он даже не берет значение по умолчанию из метаданных DP.
Вопрос. В чем проблема с этим сценарием? Почему две другие привязки работают без проблем, а эта ведет себя так, как будто привязки вообще нет?
Примечание. Если я установлю DataContext = this
в конструкторе и заменю {TemplateBinding HeaderHeight}
на {Binding HeaderHeight}
, проблема исчезнет, и все будет работать, как задумано. Но я хотел бы знать, почему мне не нужно делать то же самое с другими привязками, чтобы заставить их работать.
XAML (темы/Generic.xaml):
<Style TargetType="local:KaiPanel">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:KaiPanel">
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="{TemplateBinding HeaderHeight}" />
<RowDefinition />
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Border>
<TextBlock FontSize="{TemplateBinding TextSize}"
Text="{TemplateBinding Header}" />
</Border>
</Grid>
<Grid Grid.Row="1">
<Border>
<ContentPresenter />
</Border>
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Управление контентом (C#):
public class KaiPanel : ContentControl
{
public KaiPanel()
{
this.DefaultStyleKey = typeof(KaiPanel);
}
public static readonly DependencyProperty TextSizeProperty =
DependencyProperty.Register("TextSize", typeof(double), typeof(KaiPanel), new PropertyMetadata(15.0));
public double TextSize
{
get { return (double)GetValue(TextSizeProperty); }
set { SetValue(TextSizeProperty, value); }
}
public static readonly DependencyProperty HeaderProperty =
DependencyProperty.Register("Header", typeof(String), typeof(KaiPanel), new PropertyMetadata(""));
public String Header
{
get { return (String)GetValue(HeaderProperty); }
set { SetValue(HeaderProperty, value); }
}
public static readonly DependencyProperty HeaderHeightProperty =
DependencyProperty.Register("HeaderHeight", typeof(GridLength), typeof(KaiPanel), new PropertyMetadata(new GridLength(40)));
public GridLength HeaderHeight
{
get { return (GridLength)GetValue(HeaderHeightProperty); }
set { SetValue(HeaderHeightProperty, value); }
}
}
Использование пользовательского элемента управления (XAML):
<UserControl ...>
<Grid x:Name="LayoutRoot">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<StackPanel x:Name="buttonsStackPanel" Grid.Column="0" VerticalAlignment="Center">
<!-- Some buttons here -->
</StackPanel>
<Grid Grid.Column="1">
<controls:KaiPanel x:Name="contentPanel">
<navigation:Frame x:Name="contentFrame" Source="KP">
<navigation:Frame.UriMapper>
<uriMapper:UriMapper>
<uriMapper:UriMapping Uri="KP" MappedUri="/Views/Kornelijepetak.xaml" />
<uriMapper:UriMapping Uri="KAI" MappedUri="/Views/KaiNetwork.xaml" />
</uriMapper:UriMapper>
</navigation:Frame.UriMapper>
</navigation:Frame>
</controls:KaiPanel>
</Grid>
</Grid>
</UserControl>