独自クラスのセットアクセサを用いてバインドすると反映されない?
DispatcherTimerを使用して定期的にカウントアップする処理を実装しました。
ViewModelでバインド変数にカウント値を設定する際に、独自クラスのセットアクセサを用いた場合、
バインドした値が反映されないようなのですが、どういった理由なのでしょうか?
試したこと
①独自クラス型のプロパティにカウント値を設定、SetアクセサでViewにバインドしている変数に代入
⇒反映されない
②プリミティブ型のViewにバインドしている変数に代入
⇒当たり前ですが反映される
③プリミティブ型のプロパティにカウント値を設定、SetアクセサでViewにバインドしている変数に代入
⇒反映される
①と③の差がわからないです
該当のソースコード
メインウィンドウView
xaml
1<Window x:Class="DispatcherTimerTest.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 5 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 6 mc:Ignorable="d" 7 Title="MainWindow" Height="450" Width="800"> 8 <StackPanel> 9 <Label Content="{Binding LabelContent1}" /> 10 <Label Content="{Binding LabelContent2}" /> 11 <Label Content="{Binding LabelContent3}" /> 12 </StackPanel> 13</Window>
コードビハインド
C#
1using DispatcherTimer; 2using System; 3using System.Windows; 4using System.Windows.Navigation; 5using static DispatcherTimerTest.ViewModel; 6 7namespace DispatcherTimerTest 8{ 9 /// <summary> 10 /// MainWindow.xaml の相互作用ロジック 11 /// </summary> 12 public partial class MainWindow : Window 13 { 14 public MainWindow() 15 { 16 InitializeComponent(); 17 18 DataContext = ViewModel.Instance; 19 } 20 } 21} 22
ViewModel
C#
1using System; 2using System.Collections.Generic; 3using System.Collections.ObjectModel; 4using System.ComponentModel; 5using System.Linq; 6using System.Runtime.CompilerServices; 7using System.Text; 8using System.Threading.Tasks; 9 10namespace DispatcherTimerTest 11{ 12 public class ViewModel : INotifyPropertyChanged 13 { 14 public static ViewModel Instance { get; } = new ViewModel(); 15 public System.Windows.Threading.DispatcherTimer dispatcherTimer; 16 17 private ViewModel() 18 { 19 dispatcherTimer = new System.Windows.Threading.DispatcherTimer(System.Windows.Threading.DispatcherPriority.Normal); 20 dispatcherTimer.Interval = new TimeSpan(0, 0, 0, 0, 100); 21 dispatcherTimer.Tick += DispatcherTimer_Tick; 22 dispatcherTimer.Start(); 23 } 24 25 private void DispatcherTimer_Tick(object sender, EventArgs e) 26 { 27 // 反映されない!! 28 var source = new ViewSource(); 29 source.LabelContent1++; 30 ViewModel.Instance.Source = source; 31 32 // ラベル2、3は反映される... 33 ViewModel.Instance.LabelContent2++; 34 } 35 36 public class ViewSource 37 { 38 public int LabelContent1; 39 } 40 41 public ViewSource Source 42 { 43 get => _ViewSource; 44 set 45 { 46 _ViewSource = value; 47 LabelContent1 = value.LabelContent1; 48 } 49 } 50 private ViewSource _ViewSource; 51 52 public int LabelContent1 { get => _LabelContent1; set => Set(ref _LabelContent1, value); } 53 private int _LabelContent1; 54 55 public int LabelContent2 56 { 57 get => _LabelContent2; 58 set 59 { 60 Set(ref _LabelContent2, value); 61 LabelContent3 = value; 62 } 63 } 64 private int _LabelContent2; 65 66 public int LabelContent3 { get => _LabelContent3; set => Set(ref _LabelContent3, value); } 67 private int _LabelContent3; 68 69 70 #region INotifyPropertyChanged 71 public event PropertyChangedEventHandler PropertyChanged; 72 protected bool Set<T>(ref T storage, T value, [CallerMemberName] string propertyName = null) 73 { 74 if (Equals(storage, value)) return false; 75 76 storage = value; 77 OnPropertyChanged(propertyName); 78 return true; 79 } 80 protected void OnPropertyChanged([CallerMemberName] string propertyName = null) 81 => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 82 #endregion 83 } 84}
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/07/17 09:32