在 ButtonBase 派生模板中使用 Button 控件
Using a Button control in a ButtonBase derived template
我们的应用程序中的按钮具有特定的外观和感觉,这些按钮以 ButtonBase
的命名样式定义,这也恰好是 Button
、[=13= 的默认样式] 和 RepeatButton
.
我们还有 ToolbarButtons
派生自 ButtonBase
并包含额外的属性,例如 Text
和 Icon
。这些用于在 ToolbarButton
.
上放置特定文本和图标
ToolbarButtons
的主题在Themes/generic.xaml
中定义如下:
<Style TargetType="{x:Type c:ToolbarButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type c:ToolbarButton}">
<Button Command="{TemplateBinding Property=Command}">
.. controls to place text and icon etc ..
</Button>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
如您所见,我在基于 ButtonBase
的控件中使用 Button
控件,并将 Command
绑定到包含的 [=] 上的 Command
12=]。这个 hack 确保我可以通过定义 Button
默认样式来覆盖 Toolbar
中使用的 'Button' 的样式。
一切似乎都很好,但在 Button
中使用 Button
感觉不对。我仍然想知道我是否做对了。有什么想法吗?
您的方法很好,但您不必在模板中使用第二个按钮,而是 ContentPresenter. Use it every time your redefine the template of a ContentControl(例如按钮)。 BasedOn 属性可用于覆盖特定按钮样式。
看起来像这样:
<Style TargetType="{x:Type c:ToolbarButton}" BasedOn="{StaticResource {x:Type ButtonBase}}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:ToolbarButton}">
<StackPanel>
<!-- Image -->
<Image Source="{TemplateBinding Image}"/>
<!-- Content -->
<ContentPresenter Content="{TemplateBinding Content}"/>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
您会发现与 ItemsControl (ListBox, ListView, etc) with the ItemsPresenter 的模板相同的机制。
更新:
考虑到您的评论,也许您应该覆盖 ContentControl 以将您的特定 chrome 应用于它:
public class ButtonContentControl : ContentControl { }
<Style TargetType="{x:Type local:ButtonContentControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:ButtonContentControl}">
<!-- Specific chrome -->
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
然后您可以在 ButtonBase 和 ToolbarButton 的模板中使用它:
<
Style TargetType="{x:Type ButtonBase}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type c:ToolbarButton}">
<ButtonContentControl>
<!-- ContentPresenter or something else -->
</ButtonContentControl>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type c:ToolbarButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type c:ToolbarButton}">
<ButtonContentControl>
.. controls to place text and icon etc ..
</ButtonContentControl>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
我们的应用程序中的按钮具有特定的外观和感觉,这些按钮以 ButtonBase
的命名样式定义,这也恰好是 Button
、[=13= 的默认样式] 和 RepeatButton
.
我们还有 ToolbarButtons
派生自 ButtonBase
并包含额外的属性,例如 Text
和 Icon
。这些用于在 ToolbarButton
.
ToolbarButtons
的主题在Themes/generic.xaml
中定义如下:
<Style TargetType="{x:Type c:ToolbarButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type c:ToolbarButton}">
<Button Command="{TemplateBinding Property=Command}">
.. controls to place text and icon etc ..
</Button>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
如您所见,我在基于 ButtonBase
的控件中使用 Button
控件,并将 Command
绑定到包含的 [=] 上的 Command
12=]。这个 hack 确保我可以通过定义 Button
默认样式来覆盖 Toolbar
中使用的 'Button' 的样式。
一切似乎都很好,但在 Button
中使用 Button
感觉不对。我仍然想知道我是否做对了。有什么想法吗?
您的方法很好,但您不必在模板中使用第二个按钮,而是 ContentPresenter. Use it every time your redefine the template of a ContentControl(例如按钮)。 BasedOn 属性可用于覆盖特定按钮样式。
看起来像这样:
<Style TargetType="{x:Type c:ToolbarButton}" BasedOn="{StaticResource {x:Type ButtonBase}}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:ToolbarButton}">
<StackPanel>
<!-- Image -->
<Image Source="{TemplateBinding Image}"/>
<!-- Content -->
<ContentPresenter Content="{TemplateBinding Content}"/>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
您会发现与 ItemsControl (ListBox, ListView, etc) with the ItemsPresenter 的模板相同的机制。
更新:
考虑到您的评论,也许您应该覆盖 ContentControl 以将您的特定 chrome 应用于它:
public class ButtonContentControl : ContentControl { }
<Style TargetType="{x:Type local:ButtonContentControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:ButtonContentControl}">
<!-- Specific chrome -->
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
然后您可以在 ButtonBase 和 ToolbarButton 的模板中使用它:
<
Style TargetType="{x:Type ButtonBase}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type c:ToolbarButton}">
<ButtonContentControl>
<!-- ContentPresenter or something else -->
</ButtonContentControl>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type c:ToolbarButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type c:ToolbarButton}">
<ButtonContentControl>
.. controls to place text and icon etc ..
</ButtonContentControl>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>