使用视图模型并在 ContentView 中调用 OnAppearing
Using a view model and calling OnAppearing in ContentView
我在我的 Xamarin Forms 5 应用程序中为我的 ContentPage
使用视图模型,并且通常从代码中的 OnAppearing()
方法调用我的视图模型中的 Init()
方法落后。
我在 ContentView
中尝试了相同的方法,但它从未达到 OnAppearing()
方法。
这是我的 ContentView
代码:
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:vm="clr-namespace:MyApp.ViewModels"
x:Class="MyApp.MyContentView">
<ContentView.BindingContext>
<vm:MyViewModel/>
</ContentView.BindingContext>
<ContentView.Content>
<StackLayout
BackgroundColor="{StaticResource PrimaryDark }"
HeightRequest="200">
<Label
Text="{Binding User.FullName}"
TextColor="White"
FontSize="Medium"
FontAttributes="Bold"
HorizontalOptions="CenterAndExpand"/>
</StackLayout>
</ContentView.Content>
</ContentView>
此内容视图的视图模型如下所示:
public class MyViewModel : BaseViewModel
{
User user;
public MyViewModel()
{
}
public User User
{
get => user;
set
{
if (user == value)
return;
user = value;
OnPropertyChanged();
}
}
public async void Init()
{
// Get user info
var data = await _dbService.GetUser();
if(data != null)
{
User = data;
OnPropertyChanged(nameof(User));
}
}
}
在我后面的代码中,这就是我正在做的:
public partial class MyContentView : ContentView
{
MyViewModel _vm;
public MyContentView()
{
InitializeComponent();
_vm = new MyViewModel();
BindingContext = _vm;
}
protected virtual void OnAppearing()
{
_vm.Init();
}
}
此模式在我的内容页面中运行良好,但在内容视图中不起作用。我在这里做错了什么?
内容视图没有内容页面那样的生命周期方法。所以当content view显示或显示在屏幕上时,开发者自定义的OnAppearing()和OnDisAppearing方法将不会被调用。
因此,如果您的页面中只有一个内容视图,您可以调用页面的 OnAppearing() 方法来执行此操作。而如果contentview不是只有一个,可以在使用contentview的实例时调用 _vm.Init();
方法
这是我所做的,它似乎运行良好。
首先,我创建了一个 ContentView
来显示弹出窗口 header,其中包括用户的头像和姓名。请注意,我在 XAML 文件中为此内容视图设置了视图模型——见下文:
<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
xmlns:vm="clr-namespace:MyApp.ViewModels"
x:Class="MyApp.Views.FlyoutHeader">
<ContentView.BindingContext>
<vm:AppViewModel/>
</ContentView.BindingContext>
<ContentView.Content>
<StackLayout
BackgroundColor="{StaticResource PrimaryDark }"
HeightRequest="200">
<xct:AvatarView
Source="{Binding UserInfo.AvatarUrl}"
Size="100"
HorizontalOptions="CenterAndExpand"
VerticalOptions="CenterAndExpand"/>
<Label
Text="{Binding UserInfo.FullName}"
TextColor="White"
FontSize="Medium"
FontAttributes="Bold"
HorizontalOptions="CenterAndExpand"
Margin="0,0,0,30"/>
</StackLayout>
</ContentView.Content>
</ContentView>
然后我创建了一个名为 AppViewModel
的视图模型,我打算在多个地方使用它,包括我上面分享的 FlyoutHeader.xaml
。这是 AppViewModel
的样子:
public class AppViewModel : BaseViewModel
{
User user { get; set; }
public AppViewModel()
{
}
public User UserInfo
{
get => user;
set
{
if (user == value)
return;
user = value;
OnPropertyChanged();
}
}
public async void Init()
{
if(user == null || user.Id == Guid.Empty)
{
var data = await _dbService.GetUser();
if(data != null)
{
UserInfo = data;
OnPropertyChanged();
}
}
}
}
最后,在FlyoutHeader.xaml.cs
的后面的代码中,我在构造函数中调用了视图模型的Init()
方法:
public partial class FlyoutHeader : ContentView
{
AppViewModel _vm;
public FlyoutHeader()
{
InitializeComponent();
_vm = new AppViewModel();
_vm.Init();
BindingContext = _vm;
}
}
我实际上有点担心与 UI 的紧密耦合以及在构造函数中启动的 async
调用可能会占用 UI 线程并延迟它.如果有更好的方法来处理这个问题,请告诉我。
我在我的 Xamarin Forms 5 应用程序中为我的 ContentPage
使用视图模型,并且通常从代码中的 OnAppearing()
方法调用我的视图模型中的 Init()
方法落后。
我在 ContentView
中尝试了相同的方法,但它从未达到 OnAppearing()
方法。
这是我的 ContentView
代码:
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:vm="clr-namespace:MyApp.ViewModels"
x:Class="MyApp.MyContentView">
<ContentView.BindingContext>
<vm:MyViewModel/>
</ContentView.BindingContext>
<ContentView.Content>
<StackLayout
BackgroundColor="{StaticResource PrimaryDark }"
HeightRequest="200">
<Label
Text="{Binding User.FullName}"
TextColor="White"
FontSize="Medium"
FontAttributes="Bold"
HorizontalOptions="CenterAndExpand"/>
</StackLayout>
</ContentView.Content>
</ContentView>
此内容视图的视图模型如下所示:
public class MyViewModel : BaseViewModel
{
User user;
public MyViewModel()
{
}
public User User
{
get => user;
set
{
if (user == value)
return;
user = value;
OnPropertyChanged();
}
}
public async void Init()
{
// Get user info
var data = await _dbService.GetUser();
if(data != null)
{
User = data;
OnPropertyChanged(nameof(User));
}
}
}
在我后面的代码中,这就是我正在做的:
public partial class MyContentView : ContentView
{
MyViewModel _vm;
public MyContentView()
{
InitializeComponent();
_vm = new MyViewModel();
BindingContext = _vm;
}
protected virtual void OnAppearing()
{
_vm.Init();
}
}
此模式在我的内容页面中运行良好,但在内容视图中不起作用。我在这里做错了什么?
内容视图没有内容页面那样的生命周期方法。所以当content view显示或显示在屏幕上时,开发者自定义的OnAppearing()和OnDisAppearing方法将不会被调用。
因此,如果您的页面中只有一个内容视图,您可以调用页面的 OnAppearing() 方法来执行此操作。而如果contentview不是只有一个,可以在使用contentview的实例时调用 _vm.Init();
方法
这是我所做的,它似乎运行良好。
首先,我创建了一个 ContentView
来显示弹出窗口 header,其中包括用户的头像和姓名。请注意,我在 XAML 文件中为此内容视图设置了视图模型——见下文:
<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
xmlns:vm="clr-namespace:MyApp.ViewModels"
x:Class="MyApp.Views.FlyoutHeader">
<ContentView.BindingContext>
<vm:AppViewModel/>
</ContentView.BindingContext>
<ContentView.Content>
<StackLayout
BackgroundColor="{StaticResource PrimaryDark }"
HeightRequest="200">
<xct:AvatarView
Source="{Binding UserInfo.AvatarUrl}"
Size="100"
HorizontalOptions="CenterAndExpand"
VerticalOptions="CenterAndExpand"/>
<Label
Text="{Binding UserInfo.FullName}"
TextColor="White"
FontSize="Medium"
FontAttributes="Bold"
HorizontalOptions="CenterAndExpand"
Margin="0,0,0,30"/>
</StackLayout>
</ContentView.Content>
</ContentView>
然后我创建了一个名为 AppViewModel
的视图模型,我打算在多个地方使用它,包括我上面分享的 FlyoutHeader.xaml
。这是 AppViewModel
的样子:
public class AppViewModel : BaseViewModel
{
User user { get; set; }
public AppViewModel()
{
}
public User UserInfo
{
get => user;
set
{
if (user == value)
return;
user = value;
OnPropertyChanged();
}
}
public async void Init()
{
if(user == null || user.Id == Guid.Empty)
{
var data = await _dbService.GetUser();
if(data != null)
{
UserInfo = data;
OnPropertyChanged();
}
}
}
}
最后,在FlyoutHeader.xaml.cs
的后面的代码中,我在构造函数中调用了视图模型的Init()
方法:
public partial class FlyoutHeader : ContentView
{
AppViewModel _vm;
public FlyoutHeader()
{
InitializeComponent();
_vm = new AppViewModel();
_vm.Init();
BindingContext = _vm;
}
}
我实际上有点担心与 UI 的紧密耦合以及在构造函数中启动的 async
调用可能会占用 UI 线程并延迟它.如果有更好的方法来处理这个问题,请告诉我。