在 ButtonBase 派生模板中使用 Button 控件

Using a Button control in a ButtonBase derived template

我们的应用程序中的按钮具有特定的外观和感觉,这些按钮以 ButtonBase 的命名样式定义,这也恰好是 Button、[=13= 的默认样式] 和 RepeatButton.

我们还有 ToolbarButtons 派生自 ButtonBase 并包含额外的属性,例如 TextIcon。这些用于在 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>