2016-04-15 7 views
4

У меня возникла проблема с получением простой метки привязки данных для обновления при изменении целочисленного поля. Я реализовал INotifyPropertChanged, и это событие запускается, когда я изменяю значение переменных. Пользовательский интерфейс не обновляется, и метка не изменяется. Я не делал много данных в прошлом, поэтому я, вероятно, что-то пропустил, но я еще не смог его найти.привязка данных XAML, не обновляющая пользовательский интерфейс при изменении свойств

Вот что у меня есть для моего 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 
    } 

Любая помощь очень ценится.

EDIT: Я обновил свой 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> 

ответ

9

Ваша проблема связана с тем, как вы привязываете DataContext к отдельным элементам управления. Ваш ViewModel не является автоматически Singleton (единственным экземпляром только объекта), поэтому каждый раз, когда вы его укажете, вы фактически создаете отдельный экземпляр.

Если вы установите DataContext на уровне окна, ваш код должен работать должным образом.

4

Набор DataContext для Window как:

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

Вы установили DataContext для Button и Label отдельно, так что будет два разных объекта TestVM class. Command будет выполнен первым и изменит в нем значения, , а ваш Label отобразит значения из другого объекта.

 Смежные вопросы

  • Нет связанных вопросов^_^