【发布时间】:2022-09-23 18:15:00
【问题描述】:
我有一个装饰的,应该放在它的装饰元素旁边。根据自定义 Position 依赖属性的值,装饰器出现在元素的左侧或右侧。
我想使用一种样式来设置Position 属性的值。但是只有将样式添加到顶级控件的资源中才能做到这一点。如果我将样式放在任何子元素的资源中,它不会显示任何效果。
有没有一种方法可以像下面的示例一样基于每个元素设置装饰器样式?
<Window x:Class=\"StyledAdorner.MainWindow\"
xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"
xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"
xmlns:local=\"clr-namespace:StyledAdorner\">
<Window.Resources>
<Style TargetType=\"local:MyAdorner\">
<Setter Property=\"Position\" Value=\"Right\" />
</Style>
<Style TargetType=\"Button\">
<Setter Property=\"Content\" Value=\"Adorn me!\" />
<Setter Property=\"Margin\" Value=\"15\" />
<EventSetter Event=\"Click\" Handler=\"AddAdorner\" />
</Style>
</Window.Resources>
<StackPanel>
<Button />
<Button>
<Button.Resources>
<Style TargetType=\"local:MyAdorner\">
<!-- This setter has no effect! -->
<Setter Property=\"Position\" Value=\"Left\" />
</Style>
</Button.Resources>
</Button>
</StackPanel>
</Window>
我能想象的唯一解决方案是扫描装饰元素的资源以获取装饰风格。如果有,则检查是否有 Position 属性的设置器并使用此值。但这看起来像一个非常肮脏的黑客......
- 用于创建装饰器的
AddAdorner处理程序的代码:
private void AddAdorner(object sender, RoutedEventArgs e)
{
new MyAdorner((UIElement)sender);
}
-
MyAdorner的构造函数
private Path _indicator = new Path { /* details omitted */ };
public MyAdorner(UIElement adornedElement) : base(adornedElement)
{
AdornerLayer.GetAdornerLayer(AdornedElement).Add(this);
AddVisualChild(_indicator);
InvalidateMeasure();
InvalidateArrange();
}
-
装饰者是
Button的孩子吗?如果没有,您在<Button.Resources>中的样式将不适用。如何添加装饰器? -
装饰者装饰按钮,因此它不是按钮的子元素。但即使我将样式放在
StackPanel中,它也不会应用于装饰器。我认为这是因为装饰器被添加到装饰器层而不是窗口的内容呈现器中......我在我的问题中添加了代码部分。 -
那么,为什么不直接在添加装饰器时以编程方式设置
Position属性呢? -
我可以这样做,但位置是一个与设计相关的属性,我想通过样式而不是代码来设置它。使用上面提供的解决方案,我可以为该职位定义全局(应用程序范围)样式。如果我想更改它,我只需要更改样式而不是
MyAdorner的每个构造函数调用。也许我将使用MyAdorner中的附加属性来覆盖特定元素的位置... -
如果要在应用程序范围内定义属性,请设置属性的默认值?或者将
Style移动到App.xaml?