如何给我的自定义控件一个可覆盖的默认边距? [英] How to give my custom control an overridable default margin?

查看:87
本文介绍了如何给我的自定义控件一个可覆盖的默认边距?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题

我创建了一个自定义控件(OmniBox),其基本样式设置为:

I've created a custom control (OmniBox), which has its base style set with:

<Style x:Key="GridStyle" TargetType="Grid" BasedOn="{StaticResource BaseElement}">
    <Setter Property="Margin" Value="0,2" />
</Style>

但是当我使用控件时,我希望能够执行以下操作:

But when I'm using my control, I want to be able to do something like:

<UserControl.Resources>
    <Style TargetType="{x:Type ui:OmniBox}">
        <Setter Property="HorizontalAlignment" Value="Stretch"/>
        <Setter Property="Margin" Value="0,10"/> <!--Not Working?-->
    </Style>
</UserControl.Resources>
<Grid>
     <StackPanel>
           <ui:OmniBox x:Name="One"... />
           <ui:OmniBox x:Name="Two"... />
           ...

并且让我控制的所有实例都使用该默认保证金。不幸的是,我的控件没有响应资源中设置的样式。他们只是保持其默认边距 0,2。

And have all instances of my control take on that default margin. Unfortunately, my controls are not responding to the style set in the resources. They are just keeping their default margin of "0,2".

奇怪的是,如果我像这样显式设置控件的边距:

Strangely, if I explicitly set the margin on my controls like so:

           <ui:OmniBox x:Name="One" Margin="0,10" Style="OBDefaultStyle" ... />
           <ui:OmniBox x:Name="Two" Margin="0,10" ... />
           ...

他们确实使用 0,10的余量而不是 0,2。模板类型为什么不起作用?

They DO use the margin of "0,10" rather than "0,2". How come the template type isn't working?

如果相关,我的OmniBox控件模板都看起来像这样:

If it's relevant, my OmniBox control templates all look like this:

<Style TargetType="{x:Type local:OmniBox}" x:Key="OBDefaultStyle">
    <Setter Property="Template" Value="{StaticResource OBDefaultTemplate}" />
</Style>
<ControlTemplate TargetType="{x:Type local:OmniBox}" x:Key="OBDefaultTemplate">
    <Grid x:Name="PART_Grid" Style="{StaticResource GridStyle}">
        ... (Content)
    </Grid>
</ControlTemplate>






首次尝试

在我的网格样式中,我尝试将保证金设置为

In my grid style, I've tried setting Margin to

<Setter Property="Margin" 
        Value="{Binding Path=Margin, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:OmniBox}}}" />

但是,这并没有吸引模板保证金。

But it didn't help in sucking down the templated margin.

第二次尝试

我尝试创建自定义边距依赖性属性并将网格绑定到该属性:

I tried creating a custom margin dependency property and binding the grid to that:

<Style x:Key="GridStyle" TargetType="Grid" BasedOn="{StaticResource BaseElement}">
    <Setter Property="Margin" Value="{Binding Path=MyMargin, RelativeSource={RelativeSource TemplatedParent}}" />
</Style>

我的自定义属性定义为:

My custom property was defined as:

public static readonly DependencyProperty MarginProperty = DependencyProperty.Register("Margin", typeof(Thickness), typeof(OmniBox), new FrameworkPropertyMetadata(new Thickness(0,2,0,2), new PropertyChangedCallback(OnMarginChanged)));

无论如何都无效。在上面的依赖属性中设置的默认边距仍然会覆盖我尝试在样式模板中设置的边距。

Anyways it didn't work. The default margin set in the dependency property above is still overriding the margin I'm trying to set in the style template.

推荐答案

此问题,我弄清楚了我需要做什么。在控件的类中,我需要重写margin属性的默认值:

After happening on this question, I figured out what I needed to do. In the control's class, I need to override the margin property's default value:

    static OmniBox()
    {
        MarginProperty.OverrideMetadata(typeof(OmniBox), new FrameworkPropertyMetadata(new Thickness(0,2,0,2)));
    }

在那之后,我摆脱了网格部分的边距多功能框,因为控件本身带有边距。现在,当用户在OmniBox上设置 Margin属性时,它将接受默认值。

After that, I get rid of the margin on the "Grid" component of the omnibox completely, since the control itself carries a margin. Now when the user sets the "Margin" property on the OmniBox, it accepts it, if they don't, it uses the default value.

非常感谢大家为您的建议和努力。

Thank you all so much for your suggestions and effort.

这篇关于如何给我的自定义控件一个可覆盖的默认边距?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆