2016-04-15 17 views
4

整数フィールドが変更されたときに単純なデータバインドラベルを更新するのに問題があります。私はINotifyPropertChangedを実装しましたが、このイベントは変数値を変更すると発生します。 UIは更新されず、ラベルは変更されません。私は過去に多くのデータバインドを行っていないので、おそらく何か不足していますが、まだそれを見つけることができませんでした。ここで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> 

答えて

9

問題は、個々のコントロールにDataContextをバインドする方法にあります。 ViewModelは自動的にSingleton(単一インスタンスのみのオブジェクト)ではないので、指定するたびに実際に別のインスタンスを作成しています。

WindowレベルでDataContextを設定すると、コードは期待どおりに機能するはずです。 Windowため

4

設定DataContextはよう:

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

あなたは別途ButtonためDataContextLabelを設定しているので、TestVM classの2つの異なるオブジェクトが存在します。 Commandは最初に実行され、 の値を変更しますが、Labelは別のオブジェクトの値を表示します。

関連する問題