INotifyPropertyChanged 不更新值转换器

发布于 2024-10-15 04:04:14 字数 2733 浏览 14 评论 0原文

我有一些实现 INotifyPropertyChanged 接口的属性。效果很好。但在我的代码中,我还使用了一些值转换器(如果值 < 3 - 使网格为红色,如果值 > 3 且值 < 10 - 使网格为蓝色,等等)。

问题是在引发 PropertyChanged 后如何刷新值转换器? 解决方案背后有简单的代码吗? 谢谢大家,很抱歉我的英语不好!

这里有一些代码:

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
}

在这里我将我的值转换器应用到网格:

// 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);

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

乱世争霸 2024-10-22 04:04:14

如果您“正确”地完成了此操作,则 PropertyChanged 事件将导致绑定到该属性的绑定更新,当发生这种情况时,相同绑定中使用的任何转换器将重新转换值。因此,通常情况下,转换会自行发生。如果不是这种情况,您可能“不恰当地”使用了转换器,请发布一些代码,因为没有它,就不可能知道您到底做错了什么。

编辑:您使用grid.SetValue(Grid.BackgroundProperty, bin),您应该使用grid.SetBinding(Grid.BackgroundProperty, bin)因为它是一个绑定。

编辑2:这确实与转换器无关。
在示例代码中,您绑定到 IntValue,然后更改 TodayColor 并期望绑定更新,不会发生。如果您希望绑定对这两个属性做出反应,则必须使用 MultiBinding 或引发相应的事件,因为您的属性是相互依赖的。

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

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.

i.e.

    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");
            }
        }
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文