私は(MSサンプルから)オブジェクトが観測可能にするために(私も、このトピックの下部にあるポスト旧1)以下のNEW BindableViewModelクラスを使用します。WPF - SetProperty()がXAMLで{BindingableBindableObject.Text}を設定したときにCanExecuteをトリガーしないのはなぜですか?
public abstract class BindableBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged = delegate { };
protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
{
if (object.Equals(storage, value)) return false;
storage = value;
this.OnPropertyChanged(propertyName);
return true;
}
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
私は順序でのViewModelを作成するためにこれを使用したいです
public class Page1ViewModel : BindableBase
{
private TextBoxModel _firstName = null;
public TextBoxModel FirstName { get { return _firstName; } set {
if (SetProperty(ref _firstName, value))
{
SubmitCommand.RaiseCanExecuteChanged();
} } }
private TextBoxModel _surname = null;
public TextBoxModel Surname { get { return _surname; } set {
if (SetProperty(ref _surname, value))
{
SubmitCommand.RaiseCanExecuteChanged();
} } }
private DelegateCommand _submitCommand = null;
public DelegateCommand SubmitCommand { get { return _submitCommand??(_submitCommand=new DelegateCommand(SubmitExecute, SubmitCanExecute)); } }
private void SubmitExecute()
{
MessageBox.Show($"{FirstName.Text} {Surname.Text}");
}
private bool SubmitCanExecute()
{
if(string.IsNullOrEmpty(FirstName.Text))
return false;
else if(string.IsNullOrEmpty(Surname.Text))
return false;
else
return true;
}
}
メートルで:
public class TextBoxModel : BindableBase
{
private string _text = string.Empty;
// I'm going to bind this field to TextBox.Text property
public string Text { get { return _text; } set { SetProperty(ref _text, value); } }
private bool _isEnabled = true;
// I'm going to bind this field to TextBox.IsEnabled property
public bool IsEnabled { get { return _isEnabled; } set { SetProperty(ref _isEnabled, value); } }
}
その後、私のページのViewModelに、私はフィールドを定義するためにTextBoxModelを使用します。このようなものをTextBoxコントロールを、バインドしますyのXAMLビューでは、私はいつものように結合テキストボックスを設定します。
<TextBox Text="{Binding FirstName.Text, UpdateSourceTrigger=PropertyChanged}" IsEnabled="{Binding FirstName.IsEnabled}"/>
<TextBox Text="{Binding Surname.Text, UpdateSourceTrigger=PropertyChanged}" IsEnabled="{Binding Surname.IsEnabled}"/>
<Button Content="Submit" Command{Binding SubmitCommand} />
私はこれを実行すると、私はテキスト変更が動作していないことがわかりました。 setterの(SetProperty(ref _firstName、value))またはif(SetProperty(ref _surname、value))がトリガされませんでした。 TextBoxModelでプロパティを結合しないと、すべて正常に動作します。 OLD ViewModelBaseを使用すると、TextBoxModelも正常に機能しました。
新しいBindableBaseクラスを使用するときに何か忘れてしまったと思いますか?あなたの助けを探して、ありがとう!
OLD ViewModelBase:
[Obsolete("Please use BindableBase。")]
public abstract class ObservableModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public static string GetPropertyName<T>(System.Linq.Expressions.Expression<Func<T>> e)
{
var member = (System.Linq.Expressions.MemberExpression)e.Body;
return member.Member.Name;
}
protected virtual void RaisePropertyChanged<T>
(System.Linq.Expressions.Expression<Func<T>> propertyExpression)
{
RaisePropertyChanged(GetPropertyName(propertyExpression));
}
protected void RaisePropertyChanged(String propertyName)
{
System.ComponentModel.PropertyChangedEventHandler temp = PropertyChanged;
if (temp != null)
{
temp(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
}
}
}
これはどのように機能するのかわかりません。テキストが変更されたときに 'FirstName'や' Surname'を設定していないので、 'SetProperty'は呼び出されません。 * TextBoxModel内のプロパティの変更を監視する必要があります。 –
@CharlesMagerどういう意味ですか?私はFirstNameオブジェクトのTextプロパティを変更しましたが、(SetProperty(ref _firstName、value))の場合はトリガーしませんでした。しかし、FirstNameオブジェクトの内部でTextプロパティがトリガされました。なぜ(SetProperty(ref _firstName、value))トリガーしなかったのですか? –
あなたのバインディングは 'Text'プロパティになります。これは' string'です。その値を設定しようとすると、魔法のように 'TextBoxModel'が新しく作成されず、' FirstName'も設定されます。 'FirstName'が' null'なので、ただ静かに失敗します。 –