属性更改时XAML数据绑定未更新UI

本文关键字:更新 UI 数据绑定 XAML 属性 | 更新日期: 2024-09-08 02:42:22

当整数字段发生更改时,我很难获得要更新的简单数据绑定标签。我已经实现了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>

这是我的视图模型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,它起了作用。

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

属性更改时XAML数据绑定未更新UI

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

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

WindowDataContext设置为:

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

您已经分别为ButtonLabel设置了DataContext,因此TestVM将有两个不同的对象class。CCD_ 8将首先被执行并改变其中的值,而CCD_ 9显示来自另一个对象的值。