使用具有视图模型的依赖项属性来更改矩形的填充

时间:2016-05-30 08:40:12

标签: c# wpf xaml mvvm dependency-properties

我有一个带有矩形的视图,并且根据布尔变量,我想将填充设置为特定画笔。为此,我在ViewModel中添加了DependencyProperty。

public static readonly DependencyProperty FalseColorProperty = DependencyProperty.Register(
            "FalseColor",
            typeof(Brush),
            typeof(BooleanRectangleView),
            new FrameworkPropertyMetadata(Application.Current.FindResource("LightGreyBrush"), FrameworkPropertyMetadataOptions.AffectsRender));

public Brush FalseColor
{
    get { return (Brush)GetValue(FalseColorProperty); }
    set { SetValue(FalseColorProperty, value); }
}

在视图中,我使用以下触发器

为矩形添加了一种样式
<DataTrigger Binding="{Binding DataContext.Model.Variable, RelativeSource={RelativeSource AncestorType=UserControl}}" Value="false">
                        <Setter Property="Fill" Value="{Binding DataContext.FalseColor, RelativeSource={RelativeSource AncestorType=UserControl}}" />
</DataTrigger>

由于我在ViewModel中有DependencyProperty,因此在创建UserControl时我不知道如何设置它。例如,以下内容不起作用

<BooleanRectangleView FalseColor="..."/>

另外,当我运行程序时,我在ViewModel的构造函数中得到一个异常:

  

默认类型与属性FalseColor(从德语翻译)

的类型不匹配

修改

当我将FindResource转换为Brush时,我得到一个新的异常:

  

属性FalseColor的默认值不能绑定到特定线程

我想这与FindResource有关,不一定是从调度程序线程调用的?

1 个答案:

答案 0 :(得分:1)

我在这里不了解你的结构:你告诉FalseColorProperty在ViewModel层中,但是这个类叫做BooleanRectangleView,它应该是View类的名称(UserControl或类似的东西)。

在您的情况下,除了名为IsVariableTrue的bool之外,您还可以在View中使用此DP。

在您的ViewModel中,您将拥有Variable属性,该属性使您的模型中的Variable属性可访问。

在BooleanRectangleView XAMl中,您将拥有一个Style:

<Rectangle>
    <Rectangle.Style>
        <Style TargetType="{x:Type Rectangle}">
            <Setter Property="Fill" Value="{Binding RelativeSource={RelativeSource Self}, Path=Fill}"/> <!-- Binding to the Rectangle Fill property -->
            <Style.Triggers>
                <DataTrigger Property="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type BooleanRectangleView}}, Path=IsVariableTrue}" Value="False">
                    <Setter Property="Fill" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type BooleanRectangleView}}, Path=FalseColor}"/> <!-- Binding to the DP in the View -->
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Rectangle.Style>
    ...
</Rectangle>

在使用BooleanRectangleView的XAML中:

<BooleanRectangleView IsVariableTrue="{Binding Variable}"/> <!-- Binding to the ViewModel -->

在您的DP声明中:

public static readonly DependencyProperty FalseColorProperty = DependencyProperty.Register(
    "FalseColor",
    typeof(Brush),
    typeof(BooleanRectangleView),
    new FrameworkPropertyMetadata(
        Brush.Red, 
        FrameworkPropertyMetadataOptions.AffectsRender
    )
);

public Brush FalseColor
{
    get { return (Brush)GetValue(FalseColorProperty); }
    set { SetValue(FalseColorProperty, value); }
}

您想要在BooleanRectangleView的构造函数中设置DP值:

public BooleanRectangleView() {

    InitializeComponents();
    FalseColor = (Brush)Application.Current.FindResource("Infoteam_LightGreyBrush");
}

我确信这是一个更好的解决方案,但它应该可以正常工作。

被修改

将TemplateBinding替换为与RelativeSource的绑定,因为我们不在ControlTemplate中。 用DataTrigger替换Trigger,因为IsVariableTrue不存在于Rectangle中。