如何在程序中动态更改WPF矩形的样式

8

[编辑] *我忘记包括返回的异常信息了

'System.Windows.Style'不是属性'Fill'的有效值*

这是我的第一篇帖子,我已经搜索了很多相关问题,但没有找到答案。当涉及到MVVM、Prism和WPF时,我完全是个新手,而且这次任务非常困难。

我想根据Model中的布尔值(绑定通过)更改2个矩形的内容。

如果测试返回Pass(布尔值为True),则第一个矩形显示绿色,第二个矩形将显示UserControl.Resource Style x:Key="RectanglePass"的样式资源。 如果测试失败,则第一个矩形是红色的,第二个矩形显示UserControl.Resource Style x:Key="RectangleFail"的样式资源。

我有以下XAML代码:

<UserControl x:Class="Integration.Memjet.Aoqc.Views.ProcessResultView"
             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="300" d:DesignWidth="300">

 <UserControl.Resources>
    <Style x:Key="RectangleFail" TargetType="Rectangle">
        <Setter Property="Fill">
            <Setter.Value>
                <VisualBrush>
                    ....
                </VisualBrush>
            </Setter.Value>
        </Setter>
    </Style>
    <Style x:Key="RectanglePass" TargetType="Rectangle">
        <Setter Property="Fill">
            <Setter.Value>
                <VisualBrush>
                    ....
                </VisualBrush>
            </Setter.Value>
        </Setter>
    </Style>
</UserControl.Resources>
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="60"></RowDefinition>
        <RowDefinition Height="60"></RowDefinition>
        <RowDefinition></RowDefinition>
    </Grid.RowDefinitions>
    <Label VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="20">PASS</Label>
    <Rectangle Name="rectStatus" Grid.Row="1">
        <Rectangle.Style>
            <Style TargetType="{x:Type Rectangle}">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding Passed}" Value="True">
                        <Setter Property="Fill" Value="Green" />
                    </DataTrigger>
                    <DataTrigger Binding="{Binding Passed}" Value="False">
                        <Setter Property="Fill" Value="Red" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </Rectangle.Style>
    </Rectangle>

    <Rectangle Name="rectStatusImg" Width="120" Height="120" Grid.Row="2" >
        <Rectangle.Style>
            <Style TargetType="{x:Type Rectangle}">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding Passed}" Value="True">
                        <Setter Property="Fill" Value="{StaticResource RectanglePass}" />
                    </DataTrigger>
                    <DataTrigger Binding="{Binding Passed}" Value="False">
                        <Setter Property="Fill" Value="{StaticResource RectangleFail}" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </Rectangle.Style>
    </Rectangle>
</Grid>
</UserControl>

上述方法无法正常工作并返回异常。如果我将第二个Rectangle标签(rectStatusImg)替换为以下代码行:
<Rectangle Name="rectStatusImg" Style="{StaticResource RectanglePass}" Width="120" Height="120" Grid.Row="2" ></Rectangle>
工作并产生了预期的结果!但是我希望将其绑定到布尔值Passed,以便我可以通过编程进行更改。 <我真的希望我能在这里解释清楚我的问题。

事先感谢您的帮助,这个网站一直是一个宝藏和巨大的帮助。

干杯, 西蒙


你是否在任何地方设置了UserControl的DataContext?看起来一切都设置正确,包括绑定,但不清楚您是否实际设置了DataContext以向系统显示值的实际来源。 - Tim
嗨@Tim,在fileView.xaml.cs文件中,它有一个fileViewModel属性,该属性将DataContext返回为fileViewMode。有趣的是,通过将DataContext添加到网格中,它停止产生异常。 - sayo9394
1个回答

7
在您的资源中定义两个可视化画刷,并使用数据触发器创建矩形样式,如下所示:
  <VisualBrush x:Key="FailBrush">Black</VisualBrush>
    <VisualBrush x:Key="PassBrush">Red</VisualBrush>

    <Style x:Key="ColorRectangleStyle" TargetType="Rectangle">
        <Setter Property="Fill" Value="{StaticResource FailBrush}"/>
        <Style.Triggers>
            <DataTrigger Binding="{Binding Passed}" Value="False">
                <Setter Property="Fill" Value="{StaticResource PassBrush}"/>
            </DataTrigger>
        </Style.Triggers>
    </Style>

并在矩形中使用它,如下:

<Rectangle Name="rectStatusImg" Width="120" Height="120" Grid.Row="2" Style="{StaticResource ColorRectangleStyle}" />

希望它能有所帮助。

我们为什么只有一个PassBrush的DataTrigger?这是否意味着FailBrush将默认显示? - sayo9394
是的,你可以通过触发器将其更改为“passbrush”。你可以根据需要进行更改,但如果你只有两种颜色,这应该是可以的。 - D J
这太棒了。如果我能让网格不可见(Visibility =“Hidden”),那么在测试结束时我会显示它,揭示通过或失败。我遇到了问题,无法使其工作:<Border BorderBrush="Beige" BorderThickness="1" Height="300" Visibility="{Binding Passed, Converter={StaticResource BoolToVisiblity}}">... - sayo9394
有什么问题吗?另外,我在你的代码中看不到边框。你能更新一下包含XAML的问题吗? - D J
它运行了:D 谢谢@D J。我的愚蠢错误是我将可见性绑定到“Passed”!这真是魔法 :) - sayo9394

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接