Xamarin.forms 在OnNavigatedTo中更改模型后,Prism Xamarin Forms视图不会更新

Xamarin.forms 在OnNavigatedTo中更改模型后,Prism Xamarin Forms视图不会更新,xamarin.forms,prism,Xamarin.forms,Prism,棱镜6.3.0 我正在导航到一个视图,并在OnNavigatedTo方法中设置模型的一些属性。问题在于,在设置模型的属性后,视图不会更新 我的模型看起来像这样 public class Person { public string Name { get; set; } public string Email { get; set; } } 在我的ViewModel中 public Person Model { get => _model; set =>

棱镜6.3.0

我正在导航到一个视图,并在OnNavigatedTo方法中设置模型的一些属性。问题在于,在设置模型的属性后,视图不会更新

我的模型看起来像这样

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方法,但没有得到预期的结果。那么,当我导航到视图时,我应该怎么做才能用新数据更新视图呢?

使用setter而不是private变量设置模型

public void OnNavigatedTo(NavigationParameters parameters)
{
    var personModel = (Person)parameters["Model"];

    Model.Email = personModel.Email;
}
此外,您的XAML应该从Person.Email更改为Model.Email

=============已编辑============

您只设置了不调用SetProperty的模型的电子邮件,因此视图不会使用新的电子邮件集进行更新。要更新视图,需要将人物模型设置为以下值:

public class Person : BindableBase
{
    public string Name { get; set; }

    private string _email;
    public string Email
    {
        get { return _email; }
        set { SetProperty(ref _email, value); }
    }
}
或者,您可以设置Person对象,而不只是在OnNavigatedTo中设置电子邮件

public void OnNavigatedTo(NavigationParameters parameters)
{
    var personModel = (Person)parameters["Model"];

    Model = personModel;
}

使用setter而不是私有变量设置模型

public void OnNavigatedTo(NavigationParameters parameters)
{
    var personModel = (Person)parameters["Model"];

    Model.Email = personModel.Email;
}
此外,您的XAML应该从Person.Email更改为Model.Email

=============已编辑============

您只设置了不调用SetProperty的模型的电子邮件,因此视图不会使用新的电子邮件集进行更新。要更新视图,需要将人物模型设置为以下值:

public class Person : BindableBase
{
    public string Name { get; set; }

    private string _email;
    public string Email
    {
        get { return _email; }
        set { SetProperty(ref _email, value); }
    }
}
或者,您可以设置Person对象,而不只是在OnNavigatedTo中设置电子邮件

public void OnNavigatedTo(NavigationParameters parameters)
{
    var personModel = (Person)parameters["Model"];

    Model = personModel;
}

您可以看到如何使用的完整工作示例

您需要做几件关键的事情:

直接绑定到模型的属性是一件很棒的事情(坦白说,这是我在所有应用程序和演示中都做的事情)。但是,直接绑定到模型的属性意味着您需要确保模型是可观察的(实现
INotifyPropertyChanged

注意 如果要使用(如QuickStart模板),可以将其简化为(不需要使用BindableBase,任何实现
INotifyPropertyChanged
的基类,甚至只需将接口添加到类中即可):

接下来,需要设置ViewModel以接受要传递的参数。请注意,对于Prism 6.3,您有两个选项

从Prism 6.3开始,
INavigationAware
成为两个新导航界面的组合,
INavigatingAware
INavigatedAware
。正如名称所示,
INavigatingAware
处理即将发生的导航(在视图被推到导航堆栈之前),而
INavigatedAware
处理刚刚发生的导航。结果是,如果使用INavigatingAware.On NavigationTo更新模型,当视图被推到堆栈上时,它将显示电子邮件,而使用INavigatedAware.On NavigatedTo可能会导致明显的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");
        };
    }
}
最后,您需要确保绑定的不是对象类型,而是属性名。。。视图的绑定上下文(ViewModel)使用属性名
model
引用Person模型,因此XAML如下所示:

<Entry Text="{Binding Model.Email}" />

您可以看到一个完整的工作示例,说明如何使用

您需要做几件关键的事情:

直接绑定到模型的属性是一件很棒的事情(坦白说,这是我在所有应用程序和演示中都做的事情)。但是,直接绑定到模型的属性意味着您需要确保模型是可观察的(实现
INotifyPropertyChanged

注意 如果要使用(如QuickStart模板),可以将其简化为(不需要使用BindableBase,任何实现
INotifyPropertyChanged
的基类,甚至只需将接口添加到类中即可):

接下来,需要设置ViewModel以接受要传递的参数。请注意,对于Prism 6.3,您有两个选项

从Prism 6.3开始,
INavigationAware
成为两个新导航界面的组合,
INavigatingAware
INavigatedAware
。正如名称所示,
INavigatingAware
处理即将发生的导航(在视图被推到导航堆栈之前),而
INavigatedAware
处理刚刚发生的导航。结果是,如果使用INavigatingAware.On NavigationTo更新模型,当视图被推到堆栈上时,它将显示电子邮件,而使用INavigatedAware.On NavigatedTo可能会导致明显的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");
        };
    }
}
最后,您需要确保绑定的不是对象类型,而是属性名。。。视图的绑定上下文(ViewModel)使用属性名
model
引用Person模型,因此XAML如下所示:

<Entry Text="{Binding Model.Email}" />


不幸的是,它不起作用。关于XAML你是对的,当我输入问题时是个错误。我用
\u model
model
都试过了,但都不管用。我发现让它工作的唯一方法是调用
RaisePropertyChanged(“Model”)在分配之后,但我不应该显式地调用。你知道吗?我在你的问题中遗漏了一些信息。我已经更新了答案。第二种方法对我有效(将公共属性设置为新对象),我没有尝试第一种方法。感谢