我在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。我们绑定的边界在哪里?可视化树显示没有边界是我控制的一部分。如果我用硬编码值替换这两行,那么我得到一个边框。我怀疑exe中可能缺少一些东西,例如样式或适用于Border的东西?
提前感谢任何回复和任何花时间阅读的人。 干杯, 迈克尔
答案 0 :(得分:2)
我终于解决了这个问题。回答我的第一个问题“当控件模板中没有定义边框时,为什么我们在此代码中使用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)));
这就是它在Control
中的使用方式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>
在我将其粘贴到我控制的样式后,一切都按预期工作。
简单嘿? : - )))