【问题标题】:WPF binding a background color initializes but not updatingWPF绑定背景颜色初始化但不更新
【发布时间】:2016-01-07 09:09:09
【问题描述】:

我正在使用 observable 集合和 dataTemplates 创建通用面板,当我的按钮颜色(以编程方式设置)初始化时遇到问题,但一旦在运行时更改颜色保持不动。

这是我的按钮的 Xaml 代码:

<Button Grid.Column="0" Grid.Row="3" Background="{Binding Path=motionColor}" Command="{Binding Path=MotionPress}" Content="Motion" Height="51" Width="104" Style="{StaticResource MyButtonStyle}"/>

这是我的数据模板:

<DataTemplate x:Key="GenericPanelTemplate"  DataType="local:GenericPanel">

这是 GenericPanel.cs 中的相关后端代码:

运动颜色:

public Brush motionColor { get; set; }

按钮最终执行的功能(测试并运行):

public void MotionButton_Click()
        {
                motionColor = setColor((byte)Value.ON);
        }
    private Brush setColor(byte value)
    {
        switch (value)
        {
            case (byte)Value.OFF:
                return Brushes.Red;
            case (byte)Value.ON:
                return Brushes.Green;
            case (byte)Value.PROGRESS:
                return Brushes.Yellow;
            default:
                return Brushes.Gray;
        }
    }

启动时,motionColor设置为红色,按钮确实显示为红色,但是当这里的值更改为Brushes.Green时,它不再起作用(调试证明该值更改正确)。

如何使按钮检查其绑定值并更新背景属性?

如果需要更多代码请询问,我认为这些函数和 Xaml 行是唯一相关的。

感谢您的帮助。

【问题讨论】:

标签: c# wpf xaml


【解决方案1】:

您必须在包含该属性的类上实现INotifyPropertyChangedMSDN link),并通知您的属性的更改。

类似:

public GenericPanel : INotifyPropertyChanged
{
  private Brush _motionColor;
  public Brush motionColor { 
    get { return _motionColor; }; 
    set { 
      _motionColor = value; 
      OnPropertyChanged(); 
    }
  }

  /* ... the rest of your class ... */

  public event PropertyChangedEventHandler PropertyChanged;
  protected void OnPropertyChanged([CallerMemberName] string propertyName = null)  
  {        
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
  }
}

这一切都可以使用Fody(特别是the PropertyChanged add-in)自动完成,但如果您只需要这个特定属性,使用 Fody 可能会过大

更新

根据 cmets 的说法,由于 OP 似乎使用的是旧版本的 .NET 和 C#,因此这里是“更兼容”的版本:

public GenericPanel : INotifyPropertyChanged
{
  private Brush _motionColor;
  public Brush motionColor { 
    get { return _motionColor; }; 
    set { 
      _motionColor = value; 
      OnPropertyChanged("motionColor"); 
    }
  }

  /* ... the rest of your class ... */

  public event PropertyChangedEventHandler PropertyChanged;
  protected void OnPropertyChanged(string propertyName)  
  {
    var handle = PropertyChanged;
    if(handle != null) 
      handle(this, new PropertyChangedEventArgs(propertyName));
  }
}

【讨论】:

  • 嗨,[CallerMemberName] 是什么意思?
  • [CallerMemberName] 是一个参数的属性,如果它有一个默认值并且没有传入任何值,它会在该参数上设置调用者成员名称。所以在这种情况下,它将收到一个字符串以"motionColor" 作为其内容(因为我没有向OnPropertyChanged() 传递任何内容)。更多信息the MSDN
  • 这样使用无法编译,我得到“错误 2 找不到类型或命名空间名称‘CallerMemberName’(您是否缺少 using 指令或程序集引用?) c:\ users\dp27317\documents\visual studio 2010\Projects\GenericSoundMotion\GenericSoundMotion\GenericPanel.cs 310 43 GenericSoundMotion"
  • 您需要在文件顶部添加using System.Runtime.CompilerServices;
  • 如果您在 .NET 4.5 下,只需删除 [CallerMemberName],并在属性设置器上传递参数:OnPropertyChanged(nameof(motionColor)); 而不是 OnPropertyChanged();CallerMemberName 是 .NET 4.5 的补充,不适用于早期版本(好吧,如果使用 C# 5.0 或更高版本,您实际上可以使其工作,但这超出了本问题的范围)
猜你喜欢
  • 2016-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-30
  • 2014-09-10
  • 2011-11-24
  • 1970-01-01
  • 2011-04-10
相关资源
最近更新 更多