Прямоугольник не меняет цвет WPF - PullRequest
0 голосов
/ 22 октября 2018

Я пытаюсь изменить цвет прямоугольника в зависимости от ползунков дерева.B, R и G.

Поток кода: ползунки имеют привязки к набору colorClass, значения g, r и b которого зависят от слайдов.

Всякий раз, когда один из этих реквизитов изменяется, он вызываетсобытие для обновления результирующего цвета. Цвет прямоугольников задается результирующим цветом

Так что в теории при перетаскивании ползунка прямоугольник должен менять цвет.Но это не

Я получаю эту ошибку.

System.Windows.Data Error: 5 : Value produced by BindingExpression is not valid for target property.; Value='#FF0000FF' BindingExpression:Path=Result; DataItem='VM' (HashCode=64479624); target element is 'Rectangle' (Name=''); target property is 'Fill' (type 'Brush')

Вот мой XAML:

    <Label VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Row="1" Grid.Column="0" FontSize="24">R</Label>
    <Slider Maximum="255" Name="RSlider" VerticalAlignment="Center" Grid.Row="1" Grid.Column="1" Value="{Binding Path=RedValue, Mode=TwoWay}"></Slider>
    <TextBox PreviewTextInput="NumberValidationTextBox" Grid.Row="1" Grid.Column="2" Height="auto" Text="{Binding Path=RedValue, Mode=TwoWay}"></TextBox>

    <Label VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Row="2" Grid.Column="0" FontSize="24">G</Label>
    <Slider Maximum="255" Name="GSlider" VerticalAlignment="Center" Grid.Row="2" Grid.Column="1" Value="{Binding Path=GreenValue, Mode=TwoWay}"></Slider>
    <TextBox PreviewTextInput="NumberValidationTextBox" Grid.Row="2" Grid.Column="2" Text="{Binding Path=GreenValue, Mode=TwoWay}"></TextBox>

    <Label VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Row="3" Grid.Column="0" FontSize="24">B</Label>
    <Slider Maximum="255" Name="BSlider" VerticalAlignment="Center" Grid.Row="3" Grid.Column="1" Value="{Binding Path=Color.BlueValue, Mode=TwoWay}"></Slider>
    <TextBox PreviewTextInput="NumberValidationTextBox" Grid.Row="3" Grid.Column="2" Text="{Binding Path=Color.BlueValue, Mode=TwoWay}"></TextBox>

    <Rectangle Grid.Column="3" Grid.Row="1" Grid.RowSpan="3" Fill="{Binding Path=Result}"></Rectangle>

У меня есть цветовой класс, который будет сохраненв базе данных.Он имеет 3 int pro B, G и R. Вот класс:

 public class ColorModel : INotifyPropertyChanged
{
    private int _GreenValue;
    private int _RedValue;
    private int _BlueValue;

    public int GreenValue
    {
        get { return _GreenValue; }
        set
        {
            if (_GreenValue != value)
            {
                _GreenValue = value;
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs("GreenValue"));
                }
            }
        }
    }


    public int RedValue
    {
        get { return _RedValue; }
        set
        {
            if (_RedValue != value)
            {
                _RedValue = value;
                PropertyChanged(this, new PropertyChangedEventArgs("RedValue"));
            }
        }
    }


    public int BlueValue
    {
        get { return _BlueValue; }
        set
        {
            if (_BlueValue != value)
            {
                _BlueValue = value;
                PropertyChanged(this, new PropertyChangedEventArgs("BlueValue"));
            }
        }
    }

    public Color GetColor()
    {
        Color result = new Color();
        result = Color.FromScRgb(1, RedValue, GreenValue, BlueValue);

        return result;
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

Метод GetColor просто преобразует 3 свойства int в цвет.Затем у меня есть ViewModel, с 2 реквизитами 1 - это класс цвета, а один - цвет (Цвет результата), это свойство, из которого я хочу, чтобы мой прямоугольник получал свой цвет.

Основной код:

        public ColorModel Col;

    public MainWindow()
    {
        InitializeComponent();
        Col = new ColorModel();
        var VM = new VM();
        VM.Color = Col;
        this.DataContext = VM;
    }

И если это поможет, вот ViewModel.

public class VM : INotifyPropertyChanged
{
    private ColorModel _Color { get; set; }
    public Color Result { get; set; }

    public ColorModel Color
    {
        get { return _Color; }
        set
        {
            _Color = value;
            Result = _Color.GetColor();

            _Color.PropertyChanged += _Color_PropertyChanged;

            if(PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs("Result"));

            }

        }
    }

    private void _Color_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {

        Result = _Color.GetColor();
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs("Result"));

        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

Я очень благодарен за каждый ответ!Я новичок в WPF.

Ответы [ 2 ]

0 голосов
/ 22 октября 2018

Тип свойства Fill: Brush, а не Color.

. Вы можете использовать SolidColorBrush следующим образом:

<Rectangle ...>
    <Rectangle.Fill>
        <SolidColorBrush Color="{Binding Result}"/>
    </Rectangle.Fill>
</Rectangle>

Кроме того,вы также можете переместить свойство Result в ваш класс ColorModel и связать его так же, как вы привязываете значения Slider.Таким образом, вы избежите сложной обработки события PropertyChanged в модели представления.

<SolidColorBrush Color="{Binding Color.Result}"/>

ColorModel будет выглядеть следующим образом:

public class ColorModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    private int red;
    private int green;
    private int blue;

    public int RedValue
    {
        get { return red; }
        set
        {
            if (red != value)
            {
                red = value;
                OnPropertyChanged(nameof(RedValue));
                OnPropertyChanged(nameof(Result));
            }
        }
    }

    public int GreenValue
    {
        get { return green; }
        set
        {
            if (green != value)
            {
                green = value;
                OnPropertyChanged(nameof(GreenValue));
                OnPropertyChanged(nameof(Result));
            }
        }
    }

    public int BlueValue
    {
        get { return blue; }
        set
        {
            if (blue != value)
            {
                blue = value;
                OnPropertyChanged(nameof(BlueValue));
                OnPropertyChanged(nameof(Result));
            }
        }
    }

    public Color Result
    {
        get
        {
            return Color.FromRgb((byte)red, (byte)green, (byte)blue);
        }
    }
}
0 голосов
/ 22 октября 2018

Rectangle.Fill является объектом Brush, а не Color.

Вам необходимо добавить класс IValueConverter, который будет преобразовывать между вашим свойством ViewModel и экземпляром SolidColorBrush.

public class ColorToSolidColorBrushConverter: IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value is Color color)
            return new SolidColorBrush(color);

        return DefaultValue;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        var brush = value as SolidColorBrush;
        return brush?.Color;
    }

    public SolidColorBrush DefaultValue { get; } = Brushes.Fuchsia;
}

Использование

<Window ...>
    <Window.Resources>
        <ColorToSolidColorBrushConverter x:Key="ColorToSolidColorBrushConverter" />
    </Window.Resources>

...

<Rectangle Grid.Column="3" Grid.Row="1" Grid.RowSpan="3" Fill="{Binding Path=Result, Converter={StaticResource ColorToSolidColorBrushConverter}"></Rectangle>
...