简体   繁体   English

边框画笔属性中的自定义控件不一致?

[英]Custom control inconsistency in border brush property?

I have created my own control in WPF.我在 WPF 中创建了自己的控件。 Initially I created it as a usercontrol but found the preferred way to do this is to create a class which inherits from control and then place my respective xaml in a control template inside Generic.xaml .最初我将它创建为用户控件,但发现执行此操作的首选方法是创建一个从控件继承的 class,然后将我各自的Generic.xaml放在 Generic.xaml 内的控件模板中。

This worked fine when it was in my exe but when I moved it to a dll the border disappeared from my control .这在我的 exe 中运行良好,但是当我将它移到 dll 时,边框从我的控制中消失了 My control is based off a textbox and is a pretty much a copy and paste of the textbox's control template with the addition of a button the user can click.我的控件基于文本框,几乎是文本框控件模板的复制和粘贴,并添加了一个用户可以单击的按钮。

I've identified the relevant part of the control template that is not working which is the BorderBrush="{TemplateBinding Border.BorderBrush}" bit below as well as the next line.我已经确定了控件模板的相关部分不起作用,即下面的BorderBrush="{TemplateBinding Border.BorderBrush}"位以及下一行。

<Style TargetType="{x:Type local:ButtonBox}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:ButtonBox}">
                <mwt:ListBoxChrome 
                        Background="{TemplateBinding Panel.Background}"
                        BorderBrush="{TemplateBinding Border.BorderBrush}"
                        BorderThickness="{TemplateBinding Border.BorderThickness}"
                        RenderMouseOver="{TemplateBinding UIElement.IsMouseOver}"
                        RenderFocused="{TemplateBinding UIElement.IsKeyboardFocusWithin}"
                        Name="Bd"
                        SnapsToDevicePixels="True">

I understand template binding but I don't understand why we are binding to Border.BorderBrush .我了解模板绑定,但我不明白我们为什么要绑定到Border.BorderBrush Where is the border that we are binding to?我们绑定的border在哪里? The visual tree shows no border that is part of my control.可视化树没有显示属于我的控件的边框。 If I replace these 2 lines with hard coded values then I get a border.如果我用硬编码值替换这两行,那么我会得到一个边框。 I suspect there might be something missing from the dll that the exe has such as a style or something that applies to Border??我怀疑 dll 中可能缺少某些东西,exe 具有诸如样式或适用于 Border 的东西?

Thanks in advance for any replies and anyone who took the time to read.提前感谢您的任何回复以及任何花时间阅读的人。 Cheers, Michael干杯,迈克尔

I finally got this sorted out.我终于解决了这个问题。 To answer my first question "Why are we using Border.BorderBrush in this code when there is no border defined in the control template":要回答我的第一个问题“当控件模板中没有定义边框时,为什么我们在此代码中使用 Border.BorderBrush”:

BorderBrush="{TemplateBinding Border.BorderBrush}"

The border in Border.BorderBrush is there because the dependency property is defined on the Border class. Border.BorderBrush 中的边框在那里,因为依赖属性是在边框 class 上定义的。 Although Control has a dependency property of BorderBrush the property is actually defined in Border.尽管 Control 具有 BorderBrush 的依赖属性,但该属性实际上是在 Border 中定义的。 ie, this is how is it defined in Border即,这就是它在 Border 中的定义方式

BorderBrushProperty = DependencyProperty.Register("BorderBrush", typeof(Brush), typeof(Border), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.SubPropertiesDoNotAffectRender | FrameworkPropertyMetadataOptions.AffectsRender, new PropertyChangedCallback(Border.OnClearPenCache)));

and this is how it is used in Control这就是它在控制中的使用方式

BorderBrushProperty = Border.BorderBrushProperty.AddOwner(typeof(Control), new FrameworkPropertyMetadata(Border.BorderBrushProperty.DefaultMetadata.DefaultValue, FrameworkPropertyMetadataOptions.None));

The key point here is that Control does not define its own dependency property of BorderBrush, instead it uses AddOwner to associate itself with the existing dependency property.这里的关键点是Control没有定义自己的BorderBrush依赖属性,而是使用AddOwner将自己与已有的依赖属性关联起来。 This is why it is defined as Border.BorderBrush in the control template even though the textbox does not have a border in its control template.这就是为什么它在控件模板中定义为 Border.BorderBrush 即使文本框在其控件模板中没有边框。

The answer to my second question "where is this value set", is that it is set in the textbox's default style.我的第二个问题“这个值在哪里设置”的答案是它是在文本框的默认样式中设置的。 I can get a look at the default style for a textbox by doing this:通过执行以下操作,我可以查看文本框的默认样式:

            var style = (Style)Application.Current.TryFindResource(typeof(TextBox));
            if (style == null) return;
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;
            StringBuilder sb = new StringBuilder();
            XmlWriter writer = XmlWriter.Create(sb, settings);
            XamlWriter.Save(style, writer);
            MessageBox.Show(sb.ToString());

Once we run this code we can see in the style were both properties are hard coded.运行此代码后,我们可以在样式中看到两个属性都是硬编码的。 This seems odd to me but this is apparently the way it has been done.这对我来说似乎很奇怪,但这显然是它已经完成的方式。

  <Setter Property="Border.BorderBrush">
    <Setter.Value>
      <LinearGradientBrush StartPoint="0,0" EndPoint="0,20" MappingMode="Absolute">
        <LinearGradientBrush.GradientStops>
          <GradientStop Color="#FFABADB3" Offset="0.05" />
          <GradientStop Color="#FFE2E3EA" Offset="0.07" />
          <GradientStop Color="#FFE3E9EF" Offset="1" />
        </LinearGradientBrush.GradientStops>
      </LinearGradientBrush>
    </Setter.Value>
  </Setter>
  <Setter Property="Border.BorderThickness">
    <Setter.Value>
      <Thickness>1,1,1,1</Thickness>
    </Setter.Value>
  </Setter>

After I copy pasted that into the style for my control everything worked as expected.在我将其复制粘贴到我的控件样式中后,一切都按预期工作。

Simple hey?简单嘿? :-))) :-)))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM