我正在尝试从XAML设置同一用户控件的多个实例的fill属性,以便区分它们。我在控件的C#代码隐藏中使用依赖属性,并在实例化控件时引用XAML中的依赖属性。这是我尝试过的简化示例,首先是用户控件的XAML:
<UserControl x:Class="RectangleFillUserControlTest.RectangleFillTest"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="50" d:DesignWidth="150">
<Grid>
<Rectangle x:Name="rect" HorizontalAlignment="Left" Height="50" Stroke="Black" VerticalAlignment="Top" Width="150"/>
</Grid>
</UserControl>
现在代码隐藏:
namespace RectangleFillUserControlTest
{
public partial class RectangleFillTest : UserControl
{
SolidColorBrush fillBrush;
public static readonly DependencyProperty FillColourProperty = DependencyProperty.Register
("FillColour", typeof(string), typeof(RectangleFillTest), new PropertyMetadata(string.Empty));
public string FillColour
{
get { return (string)GetValue(FillColourProperty); }
set
{
SetValue(FillColourProperty, value);
if (value == "red") fillBrush = new SolidColorBrush(Colors.Red);
else fillBrush = new SolidColorBrush(Colors.Green);
rect.Fill = fillBrush;
}
}
public RectangleFillTest()
{
InitializeComponent();
}
}
}
我在主窗口中实例化控件并尝试将填充颜色设置为红色:
<Window x:Class="RectangleFillUserControlTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:RectangleFillUserControlTest"
Title="MainWindow" Height="350" Width="525">
<Grid Background="#FF1D2CC3">
<local:RectangleFillTest FillColour="red"/>
</Grid>
</Window>
但即使我运行项目,矩形仍未填充。有人可以帮忙吗?
干杯,
添
答案 0 :(得分:5)
我将解释为什么不起作用以及如何解决。
1.-仅当usercontrol在可视化树中具有该依赖项属性时才会调用依赖项属性。
如果你想以这种方式做,你需要添加例如:
new PropertyMetadata(string.Empty, ValueChanged));
并且更改了值:
public static readonly DependencyProperty FillColourProperty = DependencyProperty.Register
("FillColour", typeof(string), typeof(RectangleFillTest), new PropertyMetadata(string.Empty, ValueChanged));
private static void ValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var control = d as RectangleFillTest;
var fillBrush = new SolidColorBrush();
if (control.FillColour == "red")
fillBrush = new SolidColorBrush(Colors.Red);
else
fillBrush = new SolidColorBrush(Colors.Green);
control.rect.Fill = fillBrush;
}
public string FillColour
{
get
{
return (string)GetValue(FillColourProperty);
}
set
{
SetValue(FillColourProperty, value);
}
}
这对你的逻辑是明确的,如果你需要一个更通用的代码用于任何颜色等,使用将属性绑定到矩形,请告诉我。
答案 1 :(得分:5)
您的依赖项属性有两个问题。
首先,它的类型应该是Brush
,而不是字符串,因为这是WPF控件的属性使用的类型,例如Shape.Fill
或Control.Background
。 WPF在XAML中提供从“Red”或“#FFFF0000”等字符串到类型Brush的自动类型转换。
其次,除了在CLR包装器的setter方法中调用SetValue
之外,您不应该有任何其他内容。原因在MSDN上的XAML Loading and Dependency Properties文章中进行了解释:
因为当前的WPF实现了XAML处理器的行为 对于属性设置完全绕过包装器,你不应该 将任何其他逻辑放入包装器的set定义中 您的自定义依赖属性。如果你把这样的逻辑放在集合中 定义,然后在属性时不执行逻辑 在XAML而不是代码中设置。
因此,您的依赖项属性声明应如下所示:
public static readonly DependencyProperty FillBrushProperty =
DependencyProperty.Register(
"FillBrush", typeof(Brush), typeof(RectangleFillTest));
public Brush FillBrush
{
get { return (Brush)GetValue(FillBrushProperty); }
set { SetValue(FillBrushProperty, value); }
}
要对属性更改做出反应,现在可以使用属性元数据注册PropertyChangedCallback。但是你不需要在这里这样做,因为你可以简单地在UserControl的XAML中绑定属性,如下所示:
<Rectangle Fill="{Binding FillBrush,
RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}" ... />
答案 2 :(得分:0)
您需要将Dependency属性绑定到UserControl的xaml中Rectangle的Fill属性。你会有这样的事情:
<Rectangle x:Name="rect" Fill="{Binding FillColour, RelativeSource={RelativeSource FindAncestor, AncestorType=RectangleFillTest}}" HorizontalAlignment="Left" Height="50" Stroke="Black" VerticalAlignment="Top" Width="150"/>
此外,在您的依赖项属性中,它的类型应该是Brush,而不是String。