简体   繁体   中英

INotifyPropertyChanged does not update Value Converter

I have some properties which implement the INotifyPropertyChanged interface. It works fine. But in my code I also use some value converters (if value < 3 - make grid red, if value >3 and value < 10 - make grid blue, etc.).

The problem is how to refresh value converter after PropertyChanged was raised? Is there simple code behind solution? Thanks all and sorry for my bad English!

Here some code:

public class NotifyColors : INotifyPropertyChanged
{
    private Color _TodayColor;
    public Color TodayColor
    {
        get
        {
            return _TodayColor;
        }
        set
        {
            if (_TodayColor != value)
            {
                _TodayColor = value;
                OnPropertyChanged("TodayColor");
            }
        }

    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void OnPropertyChanged(String info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
            // it raised correctly when I change color with color picker control
        }
    }
}

// here is value converter
[ValueConversion(typeof(object), typeof(Brush))]
public class PositionToBackgroundConverter : IValueConverter
{
    ModulePreferences ModulePrefs;
    public PositionToBackgroundConverter(ModulePreferences ModulePrefs)
    {
        this.ModulePrefs = ModulePrefs;
    }

    #region IValueConverter Member

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (ModulePrefs.UseColoringByPosition)
        {
            try
            {
                if (value != null)
                {
                    short value_short = (short)value;
                    if (value_short <= 3)
                        return (Brush)new SolidColorBrush(ModulePrefs.NotifyColorsObj._TodayColor); // here is changing property
                    else
                        return (Brush)new SolidColorBrush(ModulePrefs.NotifyColorsObj.T100PlusColor);
                }
                else
                    return Brushes.Transparent;
            }
            catch
            {
                return Brushes.Transparent;
            }
        }
        else
            return Brushes.Transparent;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return null;
    }

    #endregion
}

And here I apply my value converter to the grid:

// assign backgroundconverter
var grid = new FrameworkElementFactory(typeof(Grid));
bin = new Binding();
bin.Path = new PropertyPath(string.Format("DataItem.{0}", LastPositionColumnName));
bin.Converter = new PositionToBackgroundConverter(ProjectViewObj.ModulePrefs);
grid.SetValue(Grid.BackgroundProperty, bin);

If you have done it "correctly" the PropertyChanged event will cause an update of the bindings which bind to that property, when this occurs any converters that are used in the same binding will reconvert the values. So normally the conversions happen on their own. If this is not the case you are probably using the converters "inappropriately", please post some code because without it it's quite impossible to tell what exactly you are doing wrong.

Edit: You use grid.SetValue(Grid.BackgroundProperty, bin) , you should use grid.SetBinding(Grid.BackgroundProperty, bin) instead since it is a binding.

Edit2: This really has nothing to do with converters.
In your sample code you bind to IntValue , then you change TodayColor and expect the binding to be updated, not gonna happen . If you want the binding to react to both properties you have to either use a MultiBinding or raise the respective events since your properties are interdependent.

ie

    private Color _TodayColor;
    public short _IntValue;

    public short IntValue
    {
        get { return _IntValue; }
        set
        {
            if (_IntValue != value)
            {
                _IntValue = value;
                OnPropertyChanged("IntValue");
                OnPropertyChanged("TodayColor");
            }
        }
    }

    public Color TodayColor
    {
        get { return _TodayColor; }
        set
        {
            if (_TodayColor != value)
            {
                _TodayColor = value;
                OnPropertyChanged("TodayColor");
                OnPropertyChanged("IntValue");
            }
        }
    }

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