WPF CustomControl可覆写预设样式

czq61nw1  于 2022-11-18  发布在  其他
关注(0)|答案(2)|浏览(165)

我有一个问题,关于在wpf的自定义控件中实现默认样式。我已经编写了自己的IconButton控件,它将两个可自定义的TextBlock放入一个按钮控件中,该控件基本上是有效的。它的外观如下:

<Style TargetType="{x:Type MyButton}" BasedOn="{StaticResource {x:Type Button}}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type MyButton}">
                    <Button>
                        <Button.Content>
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition />
                                    <ColumnDefinition />
                                </Grid.ColumnDefinitions>
                                <TextBlock
                                    Grid.Column="0"
                                    [...]>
                                </TextBlock>

                                <TextBlock
                                    Grid.Column="1"
                                    VerticalAlignment="Center"
                                    Text="{TemplateBinding Text}"
                                    [...]>
                                </TextBlock>
                            </Grid>
                        </Button.Content>
                    </Button>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

在相应的MyButton.cs中,我定义了两个TextBlock中引用的所有DependencyProperties,如下所示:

public static readonly DependencyProperty TextProperty = DependencyProperty.Register(nameof(Text), typeof(string), typeof(IconButton), new FrameworkPropertyMetadata(string.Empty));

我知道我可以在DepedencyProperty中设置默认值(这里是string.Empty),如果我这样做的话,在使用“MyButton”时定义一个新的值,它是完全可以覆盖的。但是,很明显,按钮也有常规的样式,比如宽度和高度,由于某种原因,我不能覆盖这些样式,除此之外,我还打算用默认样式为新的依赖项属性定义默认值(只是为了方便),但似乎也不起作用。
我试过两件事:(1)使用按钮样式(显然只适用于按钮的DependencyProperties,而不适用于我的新按钮)

<Button.Style>
   <Style TargetType="{x:Type Button}">
      <Setter Property="MinWidth" Value="300"/>
      <Setter Property="MinHeight" Value="24"/>
      <Setter Property="FontSize" Value="12"/>
   </Style>
</Button.Style>

或者(2)在TopLevel上定义默认样式,也就是说,就像我为模板使用的另一个常规setter一样(也适用于我的新DependencyProperties):

<Style TargetType="{x:Type MyButton}" BasedOn="{StaticResource {x:Type Button}}">
   <Setter Property="Template">...</Setter>
   <Setter Property="MinWidth">100</Setter>
</Style>

(2)看起来像是更好的解决方案,因为在我看来它应该做我想做的一切,但它根本不工作。我的两个样式更改都没有应用。(1)工作,但显然只适用于按钮样式。然而,它也不可能覆盖这些值,即,当我使用:

<local:MyButton [...] MinWidth="100"/>

它不会覆盖风格,这是我所期望的!
请记住,我是一个初学者,这是我在WPF中的第一个自定义控件!谢谢所有的建议。

mi7gmzs6

mi7gmzs61#

嘿,你是什么意思设置一个默认的模板密钥和安装该密钥?
当您使用Studio“项目”-〉“添加新项...”-〉“自定义控件(WPF)"创建自定义控件时,类模板将插入到项目中。
在这个模板中,Stuia总是插入一个静态构造函数来定义类的默认键:

static MyButton()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(MyButton), new FrameworkPropertyMetadata(typeof(MyButton)));
    }

此外,“Themes”文件夹将被添加到项目中,其中将存储“Generic.xaml”文件。
这是一个资源字典文件,它为项目中创建的所有自定义控件定义默认模板。

xzv2uavs

xzv2uavs2#

一个可行的解决方案是已经指出的方法,即在创建DependencyProperty时设置默认值。对于其他已继承的DependencyProperty,可以在静态构造函数中覆盖它们,如下所示:

static MyButton()
{
    DefaultStyleKeyProperty.OverrideMetadata(typeof(MyButton), new FrameworkPropertyMetadata(typeof(MyButton)));
    Button.FontSizeProperty.OverrideMetadata(typeof(MyButton), new FrameworkPropertyMetadata(12D, FrameworkPropertyMetadataOptions.Inherits));
    Button.MinWidthProperty.OverrideMetadata(typeof(MyButton), new FrameworkPropertyMetadata(120d, FrameworkPropertyMetadataOptions.AffectsMeasure));
    Button.MinHeightProperty.OverrideMetadata(typeof(MyButton), new FrameworkPropertyMetadata(24d, FrameworkPropertyMetadataOptions.AffectsMeasure));
}

也就是说,您可以轻松访问其他DependencyProperties并覆盖它们的默认值。“Template”属性中应用的样式似乎是硬编码的,我找不到一种方法来更改它们,而这正是我希望做的。
无论如何:这是在C#代码中,而不是在XAML中,但它确实工作,并做了所有需要的事情。

相关问题