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

Using a dependency property with a view model to change the Fill of a Rectangle

我有一个带有矩形的视图,根据一个布尔变量,我想将填充设置为特定的画笔。为此,我向 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); }
}

在View中,我用下面的Trigger给矩形添加了样式

<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 的构造函数中遇到异常:

The default type does not match the type of the property FalseColor (translated from German)

编辑:

当我将 FindResource 投射到 Brush 时,我得到一个新的异常:

The default value for the property FalseColor cannot be bound to a specific thread

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

我不明白你这里的结构:你告诉 FalseColorProperty 在 ViewModel 层中,但是 class 被称为 BooleanRectangleView,它可能应该是视图的名称 class(UserControl 或类似的东西)。

在您的情况下,除了名为 IsVariableTrue 的布尔值之外,您的视图中还会有此 DP。

在您的 ViewModel 中,您将拥有变量 属性,这使得模型中的变量 属性 可访问。

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

<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");
}

我确定有更好的解决方案,但它应该可以正常工作。

已编辑

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