XAML数据绑定在属性更改时不更新UI
问题描述:
我在更改整数字段时更新简单数据绑定标签时遇到问题。我实现了INotifyPropertChanged,当我改变我的变量值时,这个事件被触发。用户界面不会更新,标签也不会更改。过去我没有做过太多的数据绑定,所以我可能错过了一些东西,但我还没有找到它。XAML数据绑定在属性更改时不更新UI
这里是我有我的XAML:
<Window x:Class="TestBinding.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-
compatibility/2006"
xmlns:local="clr-namespace:TestBinding"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<StackPanel>
<Button Command="{Binding TestCommand, Mode=OneWay}" >
<Button.DataContext>
<local:TestVM/>
</Button.DataContext> Add 1</Button>
<Label Content="{Binding Count,
Mode=OneWay,UpdateSourceTrigger=PropertyChanged}">
<Label.DataContext>
<local:TestVM/>
</Label.DataContext>
</Label>
</StackPanel>
</Window>
这里是我的视图模型C#:
class TestVM : INotifyPropertyChanged
{
private int _count;
private RelayCommand _testCommand;
public TestVM()
{
Count=0;
}
public int Count
{
get { return _count; }
set { _count = value; OnPropertyChanged(); }
}
public void Test()
{
Count++;
}
public ICommand TestCommand
{
get
{
if (_testCommand == null)
{
_testCommand = new RelayCommand(param => this.Test(), param => true);
}
return _testCommand;
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string propertyName = "")
{
if (this.PropertyChanged != null)
{
Console.WriteLine(propertyName);
var e = new PropertyChangedEventArgs(propertyName);
this.PropertyChanged(this, e);
}
}
}
这里是我的ICommand C#(如果你需要它来复制我有什么):
public class RelayCommand : ICommand
{
#region Fields
readonly Action<object> _execute;
readonly Predicate<object> _canExecute;
#endregion // Fields
#region Constructors
public RelayCommand(Action<object> execute) : this(execute, null) { }
public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{
if (execute == null) throw new ArgumentNullException("execute");
_execute = execute;
_canExecute = canExecute;
}
#endregion // Constructors
#region ICommand Members [DebuggerStepThrough]
public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute(parameter);
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public void Execute(object parameter)
{
_execute(parameter);
}
#endregion
// ICommand Members
}
任何和所有的帮助,非常感谢。
编辑: 我更新了我的xaml toadflakz建议和它的工作。
<Window x:Class="TestBinding.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:TestBinding"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:TestVM/>
</Window.DataContext>
<StackPanel>
<Button Command="{Binding TestCommand, Mode=OneWay}" >Add 1</Button>
<Label Content="{Binding Count, Mode=OneWay,UpdateSourceTrigger=PropertyChanged}" />
</StackPanel>
</Window>
答
你的问题是你将DataContext绑定到单独控件的方式。你的ViewModel不是自动的Singleton(单实例对象),所以每次你指定它时,你实际上是在创建一个单独的实例。
如果您在Window级别设置DataContext,那么您的代码应该按预期工作。
答
设置DataContext
为Window
为:
<Window......
<Window.DataContext>
<local:TestVM/>
</Window.DataContext>
</Window>
您已设置为
DataContext
和Button
分别Label
,所以会有的TestVM
class
两个不同的对象。Command
将首先执行并更改其中的值, 而您的Label
将显示来自另一个对象的值。