WPF ControlTemplate: как предоставить значение по умолчанию для TemplateBinding?
Я пишу элемент управления WPF, который подклассы кнопки. Затем я предоставляю стиль по умолчанию в Themes\generic.xaml, который выглядит следующим образом (упрощенно):
<Style TargetType="{x:Type WPFControls:MyButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type WPFControls:MyButton}">
<Button
x:Name="PART_Button"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Я бы хотел, чтобы у пользователя была возможность изменить фон элемента управления, но если он этого не сделает, я бы хотел указать значение по умолчанию. Как мне это сделать?
Когда я делаю это, как в опубликованном коде, Background и BorderBrush имеют значение null (= не существует), если пользователь явно не указывает их (что фактически заставляет пользователя всегда предоставлять какое-то значение), но стандартные элементы управления Windows (например, Button) обеспечивают внешний вид по умолчанию, который все еще может быть настроен пользователем. Как сделать это в моем контроле?
Спасибо!
Решение Майкла Мортона:
Вы можете предоставить значения по умолчанию как сеттеры в стиле:
<Style TargetType="{x:Type TestTemplate:MyButton}">
<Setter Property="Background" Value="Red" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TestTemplate:MyButton}">
<Button
x:Name="PART_Button"
IsEnabled="{TemplateBinding IsEnabled}"
Content="{TemplateBinding Content}"
Background="{TemplateBinding Background}"
/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Использование:
<StackPanel>
<TestTemplate:MyButton Background="Blue">Explicitly blue</TestTemplate:MyButton>
<TestTemplate:MyButton>Naturally red</TestTemplate:MyButton>
</StackPanel>
4 ответа
Вы можете просто определить сеттеры в вашем стиле для двух рассматриваемых свойств.
Например, некоторые общие определения:
<LinearGradientBrush x:Key="ButtonNormalBackground" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#F3F3F3" Offset="0"/>
<GradientStop Color="#EBEBEB" Offset="0.5"/>
<GradientStop Color="#DDDDDD" Offset="0.5"/>
<GradientStop Color="#CDCDCD" Offset="1"/>
</LinearGradientBrush>
<SolidColorBrush x:Key="ButtonNormalBorder" Color="#FF707070"/>
Тогда в вашем определении стиля:
<Setter Property="Background" Value="{StaticResource ButtonNormalBackground}" />
<Setter Property="BorderBrush" Value="{StaticResource ButtonNormalBorder}" />
<Style TargetType="{x:Type WPFControls:MyButton}">
<Setter Property="Background" Value="Black">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type WPFControls:MyButton}">
<Button
x:Name="PART_Button"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Обратите внимание на вторую строку, я установил для черного цвета значение фона по умолчанию.
Когда вы объявляете свойство зависимости для ваших элементов управления, вы также объявляете значение по умолчанию как UIPropertyMetadata.
это свойство по умолчанию равно Brushes.Red, как вы можете видеть в последней строке.
public Brush MyBrush {
get { return (Brush)GetValue(MyBrushProperty); }
set { SetValue(MyBrushProperty, value); }
}
public static readonly DependencyProperty MyBrushProperty =
DependencyProperty.Register("MyBrush", typeof(Brush), typeof(MyQsFeature), new UIPropertyMetadata(Brushes.Red));
Другой способ сделать это - установить цвет по умолчанию в конструкторе вашего пользовательского элемента управления, так как конструктор всегда вызывается до того, как пользователь устанавливает какие-либо свойства, если пользователь не устанавливает их, они по умолчанию будут вашими. Фактически они всегда будут установлены вами, и тогда любые пользовательские настройки будут переопределять ваши. Это особенно эффективно, если вы хотите установить свойства, такие как Background, которые вы на самом деле не создаете, те, которые исходят от базовых классов, от которых вы наследуете.
Также возможно "наследовать" стиль по умолчанию Button
элемент путем создания образца экземпляра и ссылки на его свойства:
<Button x:Key="DefaultButton"/>
<Style TargetType="{x:Type TestTemplate:MyButton}">
<Setter Property="Background"
Value="{Binding Path=Background, Source={StaticResource DefaultButton}}" />
</Style>