具有ContentControl的WPF自定义切换按钮

时间:2018-12-07 21:21:29

标签: c# wpf

在WPF中很难实现一些琐碎的事情...

我需要设计一个具有特定外观(和感觉)的切换按钮。我做了一个小项目来演示这个问题。

“ ToggleButton用户控件”:

<UserControl x:Class="WpfApp4.UserControl1"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d"  d:DesignHeight="450" d:DesignWidth="800"
             Name="Bla">
    <UserControl.Resources>
        <Style TargetType="ToggleButton">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate>
                        <Grid>
                            <Ellipse Width="300" Height="300" Fill="Yellow"/>
                            <ContentPresenter />
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </UserControl.Resources>

    <ToggleButton 
        Width="300" Height="300">
        <ContentControl Content="{Binding ElementName=Bla, Path=MainContent}"/>
    </ToggleButton>
</UserControl>

依赖项属性:

public static DependencyProperty MainContentProperty = DependencyProperty.Register(
    "MainContent",
    typeof(object),
    typeof(UserControl1),
    null);

public object MainContent
{
    get => GetValue(MainContentProperty);
    set => SetValue(MainContentProperty, value);
}

我要使用控件的方式:

<local:UserControl1>
    <TextBlock>Whatever</TextBlock>
</local:UserControl1>

当我运行该程序时,文本框显示为“任何”,但未应用样式,则椭圆将不会显示。

这样做的正确方法是什么?

===更新===

好,到某处...终于...

现在我将其作为用户控件:

<UserControl x:Class="WpfApp4.UserControl1"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:wpfApp4="clr-namespace:WpfApp4"
             mc:Ignorable="d"  d:DesignHeight="450" d:DesignWidth="800"
             Name="Bla">
    <UserControl.Resources>
        <Style TargetType="wpfApp4:UserControl1">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate>
                        <ToggleButton>
                            <Grid>
                                <Ellipse Width="300" Height="300" Fill="Yellow"/>
                                <ContentPresenter Content="{Binding ElementName=Bla, Path=MainContent}" />
                            </Grid>
                        </ToggleButton>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </UserControl.Resources>

        <ContentPresenter/>
</UserControl>

这就是我的用法:

<local:UserControl1>
    <local:UserControl1.MainContent>
        <TextBlock>Whatever</TextBlock>
    </local:UserControl1.MainContent>
</local:UserControl1>

最后,这给了我一个应用样式的切换按钮(显示椭圆),同时还显示了文本框。

所以,这可行。这是您要使用的方式吗?还是可以简化?

1 个答案:

答案 0 :(得分:1)

应该更像

<local:UserControl1>
    <local:UserControl1.MainContent>
        <TextBlock>Whatever</TextBlock>
    </local:UserControl1.MainContent>
</local:UserControl1>

但是您应该期待覆盖ContentControl,这比使用UserControl更合适。

通过这种方式,为什么将ContentControl放在ToggleButton中? ToggleButton本身就是一个ContentControl,它具有自己的Content属性。

更新:

一切都取决于您想做什么。如果只是改变切换按钮的外观,则只需创建如下的切换按钮样式即可:

<ToggleButton>

    <TextBlock>Whatever</TextBlock>

    <ToggleButton.Style>
        <Style TargetType="{x:Type ToggleButton}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ToggleButton}">
                        <Grid>
                            <Ellipse Width="300" Height="300" Fill="Yellow"/>
                            <ContentPresenter Content="{TemplateBinding Content}" />
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ToggleButton.Style>
</ToggleButton>

Ofcorse如果您想在整个应用程序中使用样式,最好在资源字典中定义样式(例如App.xaml中的例子),给它一个键,并使用{{1}在每个切换按钮上调用它}。

如果要添加一些逻辑,则必须创建一个继承自ToggleButton的控件类,并将逻辑添加到内部。