简体   繁体   中英

How to bind UI color attribute with class property

I have a user control which is an ellipse that acts like a "led". I want to bind its "Fill" to a boolean property (State). I used for that a boolean to Color converter.

here is the user control I did:

<UserControl x:Class="Sol.Components.Led"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
... 
             xmlns:conv="clr-namespace:Sol.Converters"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">

    <Grid>
        <Ellipse Fill="{Binding Converter={StaticResource BoolToColor}}" StrokeThickness="3" Stroke="Gray"/>
    </Grid>

</UserControl>

also the converter is not recognised in the user control! I did it like this

public class BoolToColor : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value is bool)
        {
            if ((bool)value == true)
                return Colors.Green; // to replace with onColor
            else
                return Colors.Red;  // to replace with offColor
        }
        return Colors.LightGray;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value is Color)
        {
            if ((Color)value == Colors.Green) // to compare with onColor
            {
                return true;
            }
        }
        return false;
    }
}

I used a window to include 4 user contols:

<Window x:Class="Sol.Menu.Leds"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:led="clr-namespace:Sol.Components"
        xmlns:conv="clr-namespace:Sol.Converters"
        Title="Leds" Height="300" Width="300">

    <Window.Resources>
        <conv:BoolToColor x:Key="BoolToColor" />
    </Window.Resources>

    <Grid>
...
        <led:Led Grid.Column="0" Grid.Row="0" x:Name="led1" State="False"/>
        <led:Led Grid.Column="0" Grid.Row="1" x:Name="led2" State="False"/>
        <led:Led Grid.Column="1" Grid.Row="0" x:Name="led3" State="False"/>
        <led:Led Grid.Column="1" Grid.Row="1" x:Name="led4" State="False"/>
    </Grid>
</Window>

and the used control class :

public partial class Led : UserControl
{
    private bool state;
    public bool State
    {
        get { return state; }
        set { state = value; }
    }

    private Color onColor;
    public Color OnColor
    {
        get { return onColor; }
        set { onColor = value; }
    }

    private Color offColor;
    public Color OffColor
    {
        get { return offColor; }
        set { offColor = value; }
    }

    public Led()
    {
        InitializeComponent();
    }
}

this is works without binding and the window shows 4 ellipses, but I am unable to change the color dynamically (from the code bedhind). any help to fix the binding?

You need to implement PropertyChanged so the UI knows a property has been changed.

Read here how it should be done: https://docs.microsoft.com/en-us/dotnet/framework/wpf/data/how-to-implement-property-change-notification

Try to bind to the State property of the UserControl :

<Ellipse Fill="{Binding Path=State, 
    RelativeSource={RelativeSource AncestorType=UserControl}, 
    Converter={StaticResource BoolToColor}}" StrokeThickness="3" Stroke="Gray"/>

You should also return a Brush instead of a Color from your converter:

public class BoolToColor : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value is bool)
        {
            if ((bool)value == true)
                return Brushes.Green; // to replace with onColor
            else
                return Brushes.Red;  // to replace with offColor
        }
        return Brushes.LightGray;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value is Brush)
        {
            if ((Brush)value == Brushes.Green) // to compare with onColor
            {
                return true;
            }
        }
        return false;
    }
}

Fill , like all other UI "color" properties, is actually a Brush value, not a Color

Change your converter to return Brushes.Red / Brushes.Green.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM