自定义控件上的WPF控件模板

我在WPF中创建了自己的控件。 最初,我将它创建为一个用户控件,但发现首选的方法是创建一个继承自控件的类,然后将各自的xaml放置在Generic.xaml中的控件模板中。 这工作得很好,当它在我的exe文件,但当我把它移动到一个dll的边界消失了我的控制。 我的控件基于文本框,几乎是复制和粘贴文本框的控件模板,并添加一个用户可以单击的按钮。 我已经确定了不在工作的控件模板的相关部分,即下面的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">

我理解模板绑定,但我不明白为什么我们绑定到Border.BorderBrush。 我们绑定的边界在哪里? 可视化树不显示属于我的控件的边框。 如果我用硬编码值替换这两行,那么我会得到一个边界。 我怀疑可能有某些东西缺失的DLL exe文件,如样式或适用于边框?

预先感谢任何回复以及花时间阅读的人。 干杯,迈克尔


我终于搞清楚了。 为了回答我的第一个问题:“为什么我们在控制模板中没有定义边界时在代码中使用Border.BorderBrush”:

BorderBrush="{TemplateBinding Border.BorderBrush}"

Border.BorderBrush中的边框存在,因为依赖属性是在Border类中定义的。 尽管Control具有BorderBrush的依赖属性,但该属性实际上是在Border中定义的。 即,这是如何在Border中定义的

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

这就是它在控制中的用法

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

这里的关键是Control没有定义它自己的BorderBrush的依赖属性,而是使用AddOwner将自己与现有的依赖属性关联起来。 这就是为什么它在控件模板中被定义为Border.BorderBrush,即使该文本框的控件模板中没有边框。

我的第二个问题“这个值设置在哪里”的答案是它在文本框的默认样式中设置。 我可以通过执行此操作来查看文本框的默认样式:

            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());

一旦我们运行这个代码,我们可以看到,这两种属性都是硬编码的。 这对我来说似乎很奇怪,但这显然是它完成的方式。

  <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>

我复制粘贴到我的控制风格后,一切都按预期工作。

简单的嘿? :-)))

链接地址: http://www.djcxy.com/p/81349.html

上一篇: WPF Control template on custom control

下一篇: Radiobutton style based off of custom ToggleButton