C# 基于布尔值更改椭圆的颜色

C# 基于布尔值更改椭圆的颜色,c#,wpf,datatrigger,C#,Wpf,Datatrigger,给定上述XAML,当属性为true时,我希望点为绿色。我假设我会用一个DataTrigger,但是我能想到的唯一方法是为每个椭圆复制它。在我看来,这似乎有点骇人,我想知道他们的解决方案是否更好。每个椭圆都基于一个属性,但这似乎又有很多重复的代码。理想情况下,我希望这个视图能够反映“站点”列表的状态,使用布尔值来确定它们是否可用。每个视图的状态都是单向的,在视图打开时不会更改 我对WPF和XAML还很陌生,无法想出一个优雅的解决方案。每次尝试某件事时我都会畏缩,因为它看起来就像是一个彻底的黑客 编

给定上述XAML,当属性为true时,我希望点为绿色。我假设我会用一个DataTrigger,但是我能想到的唯一方法是为每个椭圆复制它。在我看来,这似乎有点骇人,我想知道他们的解决方案是否更好。每个椭圆都基于一个属性,但这似乎又有很多重复的代码。理想情况下,我希望这个视图能够反映“站点”列表的状态,使用布尔值来确定它们是否可用。每个视图的状态都是单向的,在视图打开时不会更改

我对WPF和XAML还很陌生,无法想出一个优雅的解决方案。每次尝试某件事时我都会畏缩,因为它看起来就像是一个彻底的黑客

编辑:
多亏了@Alastair的回答,我才让它工作起来

因此,我将创建一个包含椭圆的自定义
UserControl

然后,您可以将数据触发器放入
UserControl
中。然后将自定义控件的
DataContext
绑定到布尔属性,然后将
DataTrigger
绑定到
UserControl
DataContext

因此,您可以保持XAML的干净

编辑:

一个基本的用户控件。这应该在单独的文件中定义,而不是在资源中定义。只需右键单击项目->添加->新建项目。。。然后选择wpfusercontrol

<UserControl x:Class="Test_WPF.MyEllipseControl"
             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">
    <Grid>
        <Ellipse  HorizontalAlignment="Center"
                  Height="25"
                  Margin="0,0,0,0"
                  Stroke="Black"
                  VerticalAlignment="Center"
                  Width="25" 
                  Fill="Red">
            <Ellipse.Style>
                <Style TargetType="Ellipse">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding Path=IsAvailable}"
                                     Value="True">
                            <Setter Property="Fill"
                                    Value="Green" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </Ellipse.Style>
        </Ellipse>
    </Grid>
</UserControl>

然后你会使用它:

<local:MyEllipseControl DataContext="{Binding Path=Station1}" />


其中,
local
名称空间只是本地项目名称空间。

另一种方法是直接将填充绑定到布尔值,并使用转换器根据需要更改样式

您的转换器可能如下所示:

    class StatusToColor : IValueConverter
    {
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                SolidColorBrush retColor = new SolidColorBrush();
                retColor.Color = System.Windows.Media.Color.FromRgb(0, 0, 0);
                if ((bool)value)
                {
                     retColor.Color = System.Windows.Media.Color.FromRgb(255, 0, 0);
                }
                else
                {
                     retColor.Color = System.Windows.Media.Color.FromRgb(0, 128, 0);
                }
                return retColor;
            }

            public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                throw new NotImplementedException();
            }
}
然后,您可以在xaml资源中定义转换器:

<Window>    
    <Window.Resources>
        <c:StatusToColor x:Key="MyConverter"/>
    </Window.Resources>
...

...
并将绑定设置为:

<Ellipse Fill="{Binding SomeProperty, Converter={StaticResource MyConverter}}" HorizontalAlignment="Center" Height="25" Margin="0,0,0,0" Stroke="Black" VerticalAlignment="Center" Width="25"/>


那么您会显示这些电台的列表吗?那个彩色圆圈是他们的名字吗?实际上不是。把它想象成一个地图传奇。每个椭圆代表楼层平面上的一个信息亭。我看到在内部用户控件中有一个椭圆。外部UserControl的DataContext是否具有IsAvailable属性?好的。我想我明白了。让我们看看进展如何。我已经更新了我的OP,以显示我的
UserControl
。我认为我所说的基本上是正确的,只是不确定如何实际使用它。至于设置数据上下文。我需要每个“站点”的属性吗。站点1、站点2等,或者是否可以使用列表并按索引引用它们?电台[0],电台[1],等等?@lose\u the\u格林:嗯,这真的取决于你有多少台。如果你有<5个左右,我可能会选择单独的属性。如果您有很多,那么可能需要考虑使用
ItemsControl
或其他一些列表控件来轻松显示它们的列表。很抱歉,答案含糊不清,这取决于您希望它看起来像什么以及ViewModel的设置方式。这是一个很小的数目,所以为每个对象使用一个属性不会太糟糕。但我仍然不确定如何实际调用UserControl。类似于
?有些事告诉我,这并不容易