【问题标题】:XAML Data Binding not updating UI when property changes属性更改时 XAML 数据绑定不更新 UI
【发布时间】:2016-08-07 11:13:32
【问题描述】:

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

【问题讨论】:

    标签: c# wpf xaml data-binding inotifypropertychanged


    【解决方案1】:

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

    如果您在窗口级别设置 DataContext,您的代码应该可以按预期工作。

    【讨论】:

      【解决方案2】:

      DataContextWindow 设置为:

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

      你已经分别为ButtonLabel设置了DataContext,所以TestVM会有两个不同的对象 classCommand 将首先执行并更改其中的值, 而您的 Label 显示来自另一个对象的值。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-08-10
        • 2016-09-23
        • 2019-03-24
        • 2020-02-11
        • 2015-04-06
        • 1970-01-01
        相关资源
        最近更新 更多