属性更改时,XAML数据绑定不会更新UI

时间:2016-04-15 12:58:49

标签: c# wpf xaml data-binding inotifypropertychanged

在更改整数字段时,我无法获取要更新的简单数据绑定标签。我已经实现了INotifyPropertChanged,当我改变变量值时会触发此事件。 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>

这是我的View Model 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>

2 个答案:

答案 0 :(得分:10)

您的问题在于您将DataContext绑定到各个控件的方式。您的ViewModel不会自动成为Singleton(仅限单实例对象),因此每次指定它时,您实际上都在创建一个单独的实例。

如果在Window级别设置DataContext,则代码应按预期工作。

答案 1 :(得分:5)

DataContext设为Window为:

<Window......
    <Window.DataContext>
         <local:TestVM/>
    </Window.DataContext>
</Window>
  

您已为DataContextButton分别设置Label ,因此会有两个不同的{{}对象1}}   TestVMclass将首先执行并更改其中的值,   而Command显示另一个对象的值。