WPF - TextBox не будет отвечать на PropertyChanged в мультибиндинге - PullRequest
1 голос
/ 30 марта 2019

У меня есть текстовое поле, которое должно показывать шестнадцатеричное значение цвета. Приложение может быть в двух состояниях:

1) В режиме редактирования (IsEdit == true) текстовое поле привязывается к свойству модели и

2) когда текст не находится в режиме редактирования (IsEdit == false), текстовое поле привязывается к ползунку представляя цвета RGB. Изменяя каждое значение цвета с помощью ползунка, шестнадцатеричное значение в текстовом поле также изменяется, и наоборот. Текстовое поле также привязано к моему свойству модели, чтобы я мог сохранить изменения позже.

Проблема : когда приложение находится в режиме редактирования, при изменении свойства текста в текстовом поле вручную запускается конвертер и отправляется текстовое значение для модели и ползунков, но когда я меняю ползунки, текст текстового поля изменяется, но данные не отправляются в модель. Зачем?! Я перепробовал все, что мог придумать. Изменение режима привязки, notifyontargetupated ... Должно работать ... Может кто-нибудь объяснить, пожалуйста.

Я попытался упростить, поэтому, если я что-то упустил, пожалуйста, дайте мне знать.

XAML-код:

<Rectangle Grid.Column="0" Width="120" Height="120" Stroke="Black" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5,0,0,0" Fill="{Binding ElementName=tbxHexColor, Path=Text, Converter={StaticResource HexToColorConverter}}"/>
<TextBox x:Name="tbxHexColor" CharacterCasing="Upper">
    <TextBox.Style>
        <Style TargetType="TextBox">
            <Style.Triggers>
                <DataTrigger Binding="{Binding IsEdit}" Value="False">
                    <Setter Property="Text" Value="{Binding SelectedColor.RGBHex}"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding IsEdit}" Value="True">
                    <Setter Property="Text">
                    <Setter.Value>
                        <MultiBinding Converter="{StaticResource SlidersToHexConverter}" UpdateSourceTrigger="PropertyChanged">
                            <Binding ElementName="sliderRed" Path="Value"/>
                            <Binding ElementName="sliderGreen" Path="Value"/>
                            <Binding ElementName="sliderBlue" Path="Value"/>
                            <Binding Path="RGBHelper"/>
                        </MultiBinding>
                    </Setter.Value>
                    </Setter>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </TextBox.Style>
</TextBox>
<Slider x:Name="sliderRed" Grid.Column="1" Grid.Row="0" Margin="0,5,0,3" Maximum="255">
    <Slider.Style>
        <Style TargetType="Slider">
            <Style.Triggers>
                <DataTrigger Binding="{Binding IsEdit}" Value="False">
                    <Setter Property="Value" Value="{Binding SelectedColor.RGBHex, Converter={StaticResource HexToRGBConverter}, ConverterParameter=red, FallbackValue=0}"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding IsEdit}" Value="True">
                    <Setter Property="Value" Value="{Binding SelectedColor.RGBHex, Converter={StaticResource HexToRGBConverter}, ConverterParameter=red, Mode=OneTime}"/> 
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Slider.Style>
</Slider>
<Slider x:Name="sliderGreen" Grid.Column="1" Grid.Row="1" Margin="0,3" Maximum="255">
    <Slider.Style>
        <Style TargetType="Slider">
            <Style.Triggers>
                <DataTrigger Binding="{Binding IsEdit}" Value="False">
                    <Setter Property="Value" Value="{Binding SelectedColor.RGBHex, Converter={StaticResource HexToRGBConverter}, ConverterParameter=green, FallbackValue=0}"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding IsEdit}" Value="True">
                    <Setter Property="Value" Value="{Binding SelectedColor.RGBHex, Converter={StaticResource HexToRGBConverter}, ConverterParameter=green, Mode=OneTime}"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Slider.Style>
</Slider>
<Slider x:Name="sliderBlue" Grid.Column="1" Grid.Row="2" Margin="0,3" Maximum="255">
    <Slider.Style>
        <Style TargetType="Slider">
            <Style.Triggers>
                <DataTrigger Binding="{Binding IsEdit}" Value="False">
                    <Setter Property="Value" Value="{Binding SelectedColor.RGBHex, Converter={StaticResource HexToRGBConverter}, ConverterParameter=blue, FallbackValue=0}"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding IsEdit}" Value="True">
                    <Setter Property="Value" Value="{Binding SelectedColor.RGBHex, Converter={StaticResource HexToRGBConverter}, ConverterParameter=blue, Mode=OneTime}"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Slider.Style>
</Slider>

Конвертеры:

public class HexToColorConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {    
        string input = "#" + value as string;
        if (string.IsNullOrEmpty(input) || input == "#" || input.Length < 7)
        {
            input = "#00FFFFFF";
        }

        return new SolidColorBrush((Color)ColorConverter.ConvertFromString(input));            
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}



public class SlidersToHexConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        string hex = "";
        for (int i = 0; i < 3; i++)
        {
            int itemInt = System.Convert.ToInt32(values[i]);
            if (itemInt != 0)
            {
                string a = itemInt.ToString("X");
                if (a.Length == 1)
                {
                    hex += "0" + a;
                }
                else
                {
                    hex += a;
                }
            }
            else
            {
                hex += "00";
            }
        }

        return hex;                                   
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        object[] sliderValues = new object[4] { 0, 0, 0, "" };

        if (value.ToString().Length == 6)
        {
            string r = value.ToString().Substring(0, 2);
            string g = value.ToString().Substring(2, 2);
            string b = value.ToString().Substring(4, 2);

            double rr = int.Parse(r, NumberStyles.HexNumber);
            double gg = int.Parse(g, NumberStyles.HexNumber);
            double bb = int.Parse(b, NumberStyles.HexNumber);

            sliderValues[0] = (object)rr;
            sliderValues[1] = (object)gg;
            sliderValues[2] = (object)bb;
        }

        sliderValues[3] = value.ToString();

        return sliderValues;
    }
}



public class HexToRGBConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null)
        {
            return 0;
        }
        string hex = value.ToString();
        string colorHex = "0";
        switch (parameter.ToString())
        {
            case "red":
                colorHex = hex.Substring(0, 2);
                break;
            case "green":
                colorHex = hex.Substring(2, 2);
                break;
            case "blue":
                colorHex = hex.Substring(4, 2);
                break;
            default:
                break;
        }

        return int.Parse(colorHex, NumberStyles.HexNumber);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Перепробовал все в MultiBinding части XAML. Изменение: NotifyOnSourceUpdated, NotifyOnTargetUpdated, Mode, UpdateSourceTrigger ... Ничего не работает.

...