Prism 6 DelegateCommand ObservesProperty code
本文关键字:code ObservesProperty DelegateCommand Prism | 更新日期: 2023-09-27 18:21:28
大家好,我对WPF和MVVM设计模式很陌生,我从PRISM的布莱恩·拉古纳斯爵士的博客和视频中学到了很多。。但我只是想问一个小问题。。我的代码出了什么问题,对我来说不起作用…任何帮助都非常感谢。这是我的代码:
我的视图模型
public class Person : BindableBase
{
private myPErson _MyPerson;
public myPErson MyPerson
{
get { return _MyPerson; }
set
{
SetProperty(ref _MyPerson, value);
}
}
public Person()
{
_MyPerson = new myPErson();
updateCommand = new DelegateCommand(Execute, CanExecute).ObservesProperty(() => MyPerson.FirstName).ObservesProperty(() => MyPerson.Lastname);
// updateCommand = new DelegateCommand(Execute).ObservesCanExecute((p) => CanExecute); /// JUST WANNA TRY THIS BUT DUNNO HOW
}
private bool CanExecute()
{
return !String.IsNullOrWhiteSpace(MyPerson.FirstName) && !String.IsNullOrWhiteSpace(MyPerson.Lastname);
}
private void Execute()
{
MessageBox.Show("HOLA");
}
public DelegateCommand updateCommand { get; set; }
}
myModel
声明给另一个类文件
public class myPErson : BindableBase
{
private string _firstName;
public string FirstName
{
get { return _firstName; }
set
{
SetProperty(ref _firstName, value);
}
}
private string _lastname;
public string Lastname
{
get { return _lastname; }
set
{
SetProperty(ref _lastname, value);
}
}
}
查看Xaml代码
<Window x:Class="Prism6Test.Views.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:myVM="clr-namespace:Prism6Test.ViewModel"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<myVM:Person x:Key="mainVM"/>
</Window.Resources>
<Grid DataContext="{StaticResource mainVM}">
<TextBox HorizontalAlignment="Left" Height="23" Margin="217,103,0,0" TextWrapping="Wrap" Text="{Binding MyPerson.FirstName,UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" Width="120"/>
<TextBox HorizontalAlignment="Left" Height="23" Margin="217,131,0,0" TextWrapping="Wrap" Text="{Binding MyPerson.Lastname,UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" Width="120"/>
<Button Content="Button" Command="{Binding updateCommand}" HorizontalAlignment="Left" Margin="242,159,0,0" VerticalAlignment="Top" Width="75"/>
</Grid>
</Window>
我已经读过了,但它对我不起作用。我不明白如何正确地编码它。请帮我解决这个问题。。希望尽快得到答复。。thx
ObservesProperty方法不是';t观测模型';s在Prism 6 上的特性
1)你不能随心所欲地使用复杂的数据模型,所以试试
private myPErson _MyPerson;
public myPErson MyPerson
{
get { return _MyPerson; }
set
{
if (_MyPerson != null)
_MyPerson.PropertyChanged -= MyPersonOnPropertyChanged;
SetProperty(ref _MyPerson, value);
if (_MyPerson != null)
_MyPerson.PropertyChanged += MyPersonOnPropertyChanged;
}
}
private void MyPersonOnPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs)
{
updateCommand.RaiseCanExecuteChanged();
}
2) 更改您的构造函数
public Person()
{
MyPerson = new myPErson();
updateCommand = new DelegateCommand(Execute, CanExecute);
}
首先我要介绍一下您的命名。明确你的课程名称。调用ViewModel,例如PersonViewModel
,或者在应用程序不是Person
时仅调用ViewModel
,因为Person
显然是模型。此外,myPErson
是一个非常糟糕的名称,因为它与您的其他Person
类非常相似,您应该使用PascalCase作为类名。
现在转到您的代码。我对Prism
一无所知,所以我的代码只依赖于MVVM
模式,而没有Prism库的支持。
首先,我想更改模型Person
。这个类在我的代码中看起来很简单(只使用自动属性):
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public Person()
{
this.LastName = string.Empty;
this.FirstName = string.Empty;
}
}
PersonViewModel
稍微复杂一点,因为它实现了INotifyPropertyChanged
接口。我也在使用非常常见的RelayCommand,你可以在接受答案下的链接中找到它。
public class PersonViewModel : INotifyPropertyChanged
{
private Person person;
private ICommand updateCommand;
public PersonViewModel()
{
this.Person = new Person();
}
public event PropertyChangedEventHandler PropertyChanged;
public Person Person
{
get
{
return this.person;
}
set
{
this.person = value;
// if you use VS 2015 or / and C# 6 you also could use
// this.OnPropertyChanged(nameof(Person));
this.OnPropertyChanged("Person");
}
}
public ICommand UpdateCommand
{
get
{
if (this.updateCommand == null)
{
this.updateCommand = new RelayCommand<Person>(this.OpenMessageBox, this.OpenMessageBoxCanExe);
}
return this.updateCommand;
}
}
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
private void OpenMessageBox(Person person)
{
MessageBox.Show("Hola");
}
private bool OpenMessageBoxCanExe(Person person)
{
if (person == null)
{
return false;
}
if (string.IsNullOrWhiteSpace(person.FirstName) || string.IsNullOrWhiteSpace(person.LastName))
{
return false;
}
return true;
}
}
我把你的观点澄清了一点,因为它现在短多了。但总的来说,一切都保持不变。我刚刚将属性和内容重命名为:
<Window ...>
<Window.Resources>
<wpfTesst:PersonViewModel x:Key="ViewModel" />
</Window.Resources>
<Grid DataContext="{StaticResource ViewModel}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBox Grid.Row="0" TextWrapping="Wrap" Text="{Binding Person.FirstName, UpdateSourceTrigger=PropertyChanged}" />
<TextBox Grid.Row="1" TextWrapping="Wrap" Text="{Binding Person.LastName, UpdateSourceTrigger=PropertyChanged}" />
<Button Grid.Row="2" Content="Button" Command="{Binding UpdateCommand}" CommandParameter="{Binding Person}"/>
</Grid>
</Window>
总而言之,我建议您使用没有Prism库的通用MVVM模式。当你理解MVVM很好的时候,你仍然可以选择Prism。希望能有所帮助。
查看Xaml代码
<Window x:Class="Prism6Test.Views.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:myVM="clr-namespace:Prism6Test.ViewModel"
Title="MainWindow" Height="350" Width="525">
您缺少ViewModelLocator
xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
prism:ViewModelLocator.AutowireViewModel="True"