У меня есть пользовательский элемент управления, который представляет собой эллипс, который действует как «светодиод». Я хочу связать его "Fill" с логическим свойством (State). Я использовал для этого преобразователь логического значения в цвет.

Вот пользовательский контроль, который я сделал:

<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>

Также преобразователь не распознается в пользовательском управлении! Я сделал это так

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

Я использовал окно, чтобы включить 4 пользовательских элемента управления:

<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>

И используемый класс управления:

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

Это работает без привязки, и окно показывает 4 эллипса, но я не могу изменить цвет динамически (из кодового окна). Любая помощь, чтобы исправить привязку?

1
user11255515 3 Май 2019 в 13:06

3 ответа

Лучший ответ

Попробуйте связать со свойством State UserControl:

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

Вы также должны вернуть Brush вместо Color из вашего конвертера:

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;
    }
}
1
mm8 3 Май 2019 в 10:13

Вам необходимо реализовать PropertyChanged, чтобы пользовательский интерфейс знал, что свойство было изменено.

Прочтите здесь, как это следует сделать: https://docs.microsoft.com/en-us/dotnet/framework/wpf/data/how-to-implement-property-change-notification

1
programmer444 3 Май 2019 в 10:12

Fill, как и все другие «цветные» свойства пользовательского интерфейса, на самом деле является Brush значением, а не Color

Измените свой конвертер, чтобы он возвращал Brushes.Red / Brushes.Green.

0
Peregrine 3 Май 2019 в 10:11