【问题标题】:RaisePropertyChanged() is not updating the value of a single buttonRaisePropertyChanged() 没有更新单个按钮的值
【发布时间】:2015-11-28 20:13:41
【问题描述】:

我已经在我的 WPF 应用程序中使用 MVVM 有一段时间了,但是我试图让一个按钮保持禁用状态,直到它可以启用为止。没问题,我会在 ViewModel 中创建一个 bool 并将其绑定到其中。

布尔:

    private bool m_EnableLoadQuickStatsButton;
    public bool EnableLoadQuickStatsButton
    {
        get { return m_EnableLoadQuickStatsButton; }
        set { m_EnableLoadQuickStatsButton = value; RaisePropertyChanged("EnableLoadQuickStatsButton"); }
    }

XAML 按钮:

                <Button Margin="5"
                        FontSize="14"
                        IsEnabled="{Binding EnableLoadQuickStatsButton}">
                    Load Quickstats
                </Button>

数据上下文声明:

DataContext="{StaticResource MainScreenViewModel}

设计器的.gif 以及通过初始属性值启用/禁用按钮的示例:http://i.imgur.com/lpVeEBd.gif

该按钮的启用/禁用基于属性开始的任何内容。但是,更改属性不会启用/禁用我的按钮。为什么是这样?我的其他控件和属性似乎没有任何问题。

编辑:

我的类正确实现了 INotifyPropertyChanged,还有其他属性的值绑定到我的 WPF 应用程序中的控件,它们按预期工作。

Edit2:应用程序的 A.gif,显示 DataBinding 工作的其他部分:http://i.imgur.com/lIvzHv7.gif

Edit3:开始调试时的输出:

System.Windows.Data Warning: 56 : Created BindingExpression (hash=51180192) for Binding (hash=56315736)
System.Windows.Data Warning: 58 :   Path: 'EnableLoadQuickStatsButtonTest'
System.Windows.Data Warning: 60 : BindingExpression (hash=51180192): Default mode resolved to OneWay
System.Windows.Data Warning: 61 : BindingExpression (hash=51180192): Default update trigger resolved to PropertyChanged
System.Windows.Data Warning: 62 : BindingExpression (hash=51180192): Attach to System.Windows.Controls.Button.IsEnabled (hash=23804398)
System.Windows.Data Warning: 67 : BindingExpression (hash=51180192): Resolving source 
System.Windows.Data Warning: 70 : BindingExpression (hash=51180192): Found data context element: Button (hash=23804398) (OK)
System.Windows.Data Warning: 78 : BindingExpression (hash=51180192): Activate with root item MainScreenViewModel (hash=64564967)
System.Windows.Data Warning: 108 : BindingExpression (hash=51180192):   At level 0 - for MainScreenViewModel.EnableLoadQuickStatsButtonTest found accessor RuntimePropertyInfo(EnableLoadQuickStatsButtonTest)
System.Windows.Data Warning: 104 : BindingExpression (hash=51180192): Replace item at level 0 with MainScreenViewModel (hash=64564967), using accessor RuntimePropertyInfo(EnableLoadQuickStatsButtonTest)
System.Windows.Data Warning: 101 : BindingExpression (hash=51180192): GetValue at level 0 from MainScreenViewModel (hash=64564967) using RuntimePropertyInfo(EnableLoadQuickStatsButtonTest): 'False'
System.Windows.Data Warning: 80 : BindingExpression (hash=51180192): TransferValue - got raw value 'False'
System.Windows.Data Warning: 89 : BindingExpression (hash=51180192): TransferValue - using final value 'False'

Edit4:创建了一个新项目,它按预期工作,只是由于某种原因不在我当前的项目中。

【问题讨论】:

  • 您的RaisePropertyChanged 是做什么的?你的班级是否正确实现了INotifyPropertyChanged
  • 是的,所有其他属性和控件都可以正常工作。除了这个,没有任何理由。
  • 顺便说一句,通常最好将按钮绑定到ICommand 实现。然后它的启用状态将绑定到ICommand.CanExecute 的结果。
  • 在这种情况下要做的第一件事:将PresentationTraceSources.TraceLevel=High添加到绑定并观察输出窗口。
  • @Laith 我使用 LiceCap。这是一个免费的屏幕录制工具,可以输出一个 .gif 文件,但它以相当低的帧速率录制,所以它只适用于我发布的内容。

标签: c# wpf xaml mvvm


【解决方案1】:

我尝试了相同的代码,但效果很好。

代码应该是

EnableLoadQuickStatsButton = AFunctionReturnsBool();

改变属性的时候,可能你用过

m_EnableLoadQuickStatsButton = AFunctionReturnsBool();?

【讨论】:

  • 感谢您的回复。仔细检查,我也刚刚创建了一个新项目,它工作正常。我肯定会改变EnableLoadQuickStatsButton。为了保险起见,在更改布尔值后,我继续为我的视图模型中的每个属性调用RaisePropertyChanged。我还设置了适当的断点,可以验证 bool 是否已更改。
  • 并确保按钮的容器已启用?
  • 容器是指它所在的面板吗?它目前位于已启用的 DockPanel 中,是的。
【解决方案2】:

正如 cmets 中所指出的,似乎 ViewModel 被实例化了好几次,而按钮的 DataContext 中的那个与被更改的实例不同。

一个简单的测试证明了这一点。

至于一些扩展技巧...使用 MVVM 背后的想法是将视图与模型分离。我会避免使用名称暗示“按钮”或任何其他视觉元素的属性。

ViewModel 中的EnableLoadQuickStatsButton 应该称为AreQuickStatsReadyToBeLoaded 或类似的名称

【讨论】:

  • 此外,OP 最好将按钮绑定到返回 ICommand 的属性。
  • @slugster 确实,并使用CanExecute 而不是设置IsEnabled
  • 我一定会努力做到的!
猜你喜欢
  • 2014-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-21
  • 2010-09-12
  • 2021-04-22
相关资源
最近更新 更多