我已经在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
。我们要绑定到的border
在哪里?可视树没有显示边框,这是我控件的一部分。如果我用硬编码值替换这两行,则会出现边框。我怀疑dll可能缺少exe所缺少的东西,例如样式或适用于Border的东西?
预先感谢您的答复以及花时间阅读的任何人。干杯,迈克尔
我终于弄明白了。回答我的第一个问题“当控件模板中没有定义边框时,为什么在此代码中使用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>
在我将其粘贴到控件的样式中后,所有操作均按预期进行。
简单嘿? :-)))