在另一篇文章(Prism BindableBase.SetProperty())上,@ brian-lagunas表示他更喜欢将Model公开为属性并将View绑定到模型属性。他给出了以下示例代码:
public class Person : INotifyPropertyChanged
{
private string _FirstName;
private string _LastName;
public string FirstName { get { return _FirstName; } set => SetProperty(ref _FirstName, value); }
public string LastName { get { return _LastName; } set => SetProperty(ref _LastName, value); }
private void SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
{
if (!Equals(storage,value))
{
storage = value;
OnPropertyChanged(propertyName);
}
}
private void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
但是,我不确定如何绑定属性。这是否会通知财产变更?
更新: 这是我如何在模型上实现INPC?如果是这样,通过将属性放在已经支持INPC的视图模型中,我获得了什么?
@RequestMapping(value="/test/{firstNameIds}", method=RequestMethod.GET)
@ResponseBody
public String test(@PathVariable List<Integer> firstNameIds) {
//Example: pring your params
for(Integer param : firstNameIds) {
System.out.println("id: " + param);
}
return "Dummy";
}
答案 0 :(得分:4)
鉴于以下模型:
public class Person
{
public string FirstName { get; set; }
}
绑定到FirstName
属性,对FirstName的任何更新都不会有属性更改的通知。实现此目的的唯一方法是,如果您的模型实现INotifyPropertyChanged
。
也就是说,直接绑定到模型可能是一个很好的策略。作为常见示例,如果您有ListView
,则通常可以安全地绑定到ObservableCollection<SomeModel>
。如果你正在处理一个相对较小的数据集,并且可以承担重新加载数据源的开销,那么你就可以安全地使用它了。
现在就如何绑定到一个属性,给出:
public class ViewAViewModel : BindableBase
{
private Person _myPerson;
public Person MyPerson
{
get { return _myPerson; }
set { SetProperty( ref _myPerson, value ); }
}
}
您的XAML标记看起来像:
<Label Text="{Binding MyPerson.FirstName}" />
<强>更新强>
如您更新的问题中所述,是的,您可以像这样实施INotifyPropertyChanged
。请记住,BindableBase
已经为您完成了,所以根据您的示例,您可以继承BindableBase
...另一个不错的选择是,如果您使用James Montemagno的MvvmHelpers,您可以使用他的ObservableObject
1}}在您的模型上,BaseViewModel
用于您的ViewModel,它为您提供Title,SubTitle,Icon,IsBusy,IsNotBusy等属性。
这样做的好处当然是您现在可以直接绑定到模型。一个视图很少知道模型考虑以下内容:
人物模型
public class Person : 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 ); }
}
private DateTime _dob;
public DateTime DOB
{
get { return _dob; }
set { SetProperty( ref _dob, value ); }
}
}
用户个人资料ViewModel
public class UserProfileViewModel : BindableBase, INavigationAware
{
INavigationService _navigationService { get; }
IPageDialogService _pageDialogService { get; }
public UserProfileViewModel( INavigationService navigationService, IPageDialogService pageDialogService )
{
_navigationService = navigationService;
_pageDialogService = pageDialogService;
DoFooCommand = new DelegateCommand( () => _pageDialogService.DisplayAlertAsync( "Alert", "Foo", "Ok" ) );
}
private bool shouldSave = false;
private string _title;
public string Title
{
get { return _title; }
set { SetProperty( ref _title, value ); }
}
private Person _user;
public Person User
{
get { return _user; }
set { SetProperty( ref _user, value ); }
}
public DelegateCommand DoFooCommand { get; }
public void OnNavigatingTo( NavigationParameters parameters )
{
Title = AppResources.UserProfilePageTitle;
User = parameters.GetValue<Person>( "currentUser" );
User.PropertyChanged += ( sender, e ) => shouldSave = true;
}
public void OnNavigatedFrom( NavigationParameters parameters )
{
if( shouldSave )
{
// Do your persistence here.
}
}
public void OnNavigatedTo( NavigationParameters parameters )
{
User.DOB = new DateTime( 2017, 1, 1 );
}
}
用户个人资料视图
<ContentPage Title="{Binding Title}">
<StackLayout>
<Label Text="First Name" />
<Entry Text="{Binding User.FirstName}" />
<Label Text="Last Name" />
<Entry Text="{Binding User.LastName}" />
<Label Text="{Binding User.DOB}" />
<Button Text="Do Foo" Command="{Binding DoFooCommand}" />
</StackLayout>
</ContentPage>
鉴于此代码,应该注意以下几点:
1)我们的ViewModel包含各种各样的东西,这些东西与我们的模型(如命令)或Title等属性无关。它也可能会消耗INavigationService
或IPageDialogService
2)其次,我们可能想要限制用户可以编辑哪些属性,ViewModel可以编辑。
3)如果我们的模型实现INotifyPropertyChanged
,我们可以附加一个事件处理程序,让我们知道我们的模型在设置之后发生了变化,这样我们就可以保留这些变化。
4)它使XAML对我们的意图更具可读性。我们没有绑定一些名为FirstName的魔法属性。我们真的绑定到Person模型的FirstName属性。
答案 1 :(得分:0)
我不确定我是如何绑定属性的。
要绑定到模型的属性,您必须将数据绑定到公开模型及其属性的属性,即,如果您使用属性“Person”公开了模型 并且想要绑定到person的Name属性,你不需要绑定到'Person.Name'。
这是否会通知财产变更?
https://msdn.microsoft.com/en-us/library/dn736263(v=pandp.50).aspx
SetProperty方法将负责通知属性更改。