[英]Property setter not working in XAML
从Canvas
扩展了一个自定义控件,该控件只能接受Shape
类的实例作为其子级。 考虑下面的代码:
public class SvgGroup : Canvas
{
// ...
public Brush Fill
{
// Retuns the fill brush value of all the shape children, if they are all the same. Otherwise, the default value of Brush is returned
get
{
Brush rtn = default(Brush);
for (int i = 0; i < ShapeChildren.Count; i++)
{
Shape shape = ShapeChildren[i];
if (i == 0) // First loop
{
rtn = shape.Fill;
}
else if (rtn != shape.Fill) // Children shapes have different Fill value
{
return default(Brush);
}
}
return rtn;
}
// Sets the fill brush value of all the shape children
set
{
foreach (Shape shape in ShapeChildren)
{
shape.Fill = value;
}
}
}
// ...
}
问题是在XAML中设置Fill属性时,什么也没有发生。 但是,设置“在后台代码中填充”是可行的。
我当时在考虑依赖属性,但是这种情况下的实现可能会非常棘手。
我认为您应该定义两个依赖项属性,并且应该更新其中之一:
public class SvgGroup : Canvas
{
public Brush Fill
{
get { return (Brush)GetValue(FillProperty); }
set { SetValue(FillProperty, value); }
}
public static readonly DependencyProperty FillProperty
= DependencyProperty.Register(
"Fill",
typeof(Brush),
typeof(SvgGroup),
new FrameworkPropertyMetadata(Brushes.Red, OnFillPropertyChanged)
);
private static void OnFillPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
SvgGroup svg = (SvgGroup)d;
if (e.NewValue != null && !e.NewValue.Equals(e.OldValue))
{
foreach (Shape shape in d.ShapeChildren)
{
shape.Fill = (Brush)e.NewValue;
}
d.OnShapeBrushChanged(); // Note that you should call this method in some other places too.
}
}
public Brush FillDifferentBrush
{
get { return (Brush)GetValue(IsFillDifferentProperty); }
}
public static readonly DependencyProperty FillDifferentProperty
= DependencyProperty.Register(
"FillDifferentBrush",
typeof(Brush),
typeof(SvgGroup),
new PropertyMetadata(null)
);
void OnShapeBrushChanged()
{
Brush rtn = default(Brush);
for (int i = 0; i < ShapeChildren.Count; i++)
{
Shape shape = ShapeChildren[i];
if (i == 0) // First loop
{
rtn = shape.Fill;
}
else if (rtn != shape.Fill) // Children shapes have different Fill value
{
SetValue(FillDifferentProperty, default(Brush));
}
else
SetValue(FillDifferentProperty, rtn);
}
}
}
您应该正确调用OnShapeBrushChanged()
(例如,当添加新的OnShapeBrushChanged()
或单独更改其Brush或调用Fill属性时),以使其保持更新状态(类似于ItemsControl的HasItems属性)。
在任何父元素上设置属性后,其值将被所有子元素继承。 有一个PropertyChanged回调,它检查元素是否为Shape
并最终将继承的Brush应用于Shape的Fill
属性。
public static class ChildFillEx
{
public static readonly DependencyProperty ChildFillProperty =
DependencyProperty.RegisterAttached(
"ChildFill", typeof(Brush), typeof(ChildFillEx),
new FrameworkPropertyMetadata(
null,
FrameworkPropertyMetadataOptions.Inherits,
ChildFillPropertyChanged));
public static Brush GetChildFill(DependencyObject obj)
{
return (Brush)obj.GetValue(ChildFillProperty);
}
public static void SetChildFill(DependencyObject obj, Brush value)
{
obj.SetValue(ChildFillProperty, value);
}
private static void ChildFillPropertyChanged(
DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
var shape = obj as Shape;
if (shape != null)
{
shape.Fill = (Brush)e.NewValue;
}
}
}
您可以这样使用它:
<Canvas local:ChildFillEx.ChildFill="Red">
<Rectangle Width="100" Height="100" />
</Canvas>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.