如何从XAML设置WPF usercontrol属性?

时间:2015-05-13 13:03:42

标签: c# wpf xaml user-controls

我正在尝试从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>

但即使我运行项目,矩形仍未填充。有人可以帮忙吗?

干杯,

3 个答案:

答案 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.FillControl.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。