棱镜6.3.0
我导航到View,我在OnNavigatedTo方法中设置了Model的一些属性。问题是在设置模型的属性后,视图不会更新。
我的模型看起来像这样
public class Person
{
public string Name { get; set; }
public string Email { get; set; }
}
在我的ViewModel
中public Person Model
{
get => _model;
set => SetProperty(ref _model, value);
}
OnNavigatedTo方法是
public void OnNavigatedTo(NavigationParameters parameters)
{
var personModel = (Persom)parameters["Model"];
_model.Email = personModel.Email;
}
在XAML中
<Entry Text="{Binding Person.Email, Mode=TwoWay}">
</Entry>
我也尝试过OnNavigatingTo方法,但我没有达到预期的效果。那么,当我导航到视图时,如何使用新数据更新视图?
答案 0 :(得分:1)
使用setter而不是私有变量设置模型。
public void OnNavigatedTo(NavigationParameters parameters)
{
var personModel = (Person)parameters["Model"];
Model.Email = personModel.Email;
}
此外,您的XAML应该从Person.Email更改为Model.Email
=========== EDITED ============
您只设置不调用SetProperty的模型的电子邮件,因此不会使用新的电子邮件集更新视图。要更新视图,您需要将Person模型设置为以下内容:
public class Person : BindableBase
{
public string Name { get; set; }
private string _email;
public string Email
{
get { return _email; }
set { SetProperty(ref _email, value); }
}
}
或者不只是在OnNavigatedTo中设置电子邮件,您可以设置Person对象。
public void OnNavigatedTo(NavigationParameters parameters)
{
var personModel = (Person)parameters["Model"];
Model = personModel;
}
答案 1 :(得分:1)
您可以使用Prism Quickstart Templates查看完整的工作示例。
您需要做一些关键事项:
直接绑定到您的Model的属性是一件很棒的事情(坦率地说,我在所有应用程序和演示中都做了一些事情)。但是,直接绑定到Model的属性意味着您需要确保Model是Observable(实现INotifyPropertyChanged
)。
public class Person : BindableBase
{
private string _email;
public string Email
{
get => _email;
set => SetProperty(ref _email, value);
}
}
注意强>
如果您使用PropertyChanged.Fody(如QuickStart模板),您可以将其简化为(您不需要使用BindableBase,任何实现INotifyPropertyChanged
的基类,或者甚至只是将类添加到类中工作):
public class Person : BindableBase
{
public string Email { get; set; }
}
接下来,您需要设置ViewModel以接受要传递的参数。请注意,使用Prism 6.3,您有几个选择。
从Prism 6.3开始,INavigationAware
成为两个新导航界面INavigatingAware
和INavigatedAware
的组合。正如名称所示,INavigatingAware
处理即将发生的导航(在视图被推送到导航堆栈之前),而INavigatedAware
处理刚刚发生的导航。结果是,如果在将视图推入堆栈时使用INavigatingAware.OnNavigatingTo
更新模型,则会显示电子邮件,而使用INavigatedAware.OnNavigatedTo
可能会导致显着的UI更新。
无论您选择哪种方法,都可以按照以下方式设置模型:
public class ViewAViewModel : BindableBase, INavigatingAware
{
// This assumes you are using PropertyChanged.Fody as mentioned above
public Person Model { get; set; }
public void OnNavigatingTo(NavigationParameters parameters)
{
// Method 1:
Model = parameters.GetValue<Person>("Model");
// Method 2:
if(parameters.TryGetValue<Person>("Model", out Model))
{
// do something
}
// Method 3:
Model = new Person
{
Email = parameters.GetValue<string>("email");
};
}
}
注意强>
我应该注意,将Model
的密钥与ViewModel的属性命名为Model
并不重要。它可能是foobar
并且仍然有效。重要的是关键匹配如下所示:
_navigationService.NavigateAsync("ViewA", new NavigationParameters
{
{ "foo", new Person { Email = "john@doe.com" } }
});
Model = parameters.GetValue<Person>("foo");
最后需要确保您不是绑定到对象类型而是绑定属性名称...您的视图的绑定上下文(您的ViewModel)使用属性名称Model
引用Person模型,因此您的XAML那么看起来像这样:
<Entry Text="{Binding Model.Email}" />