[英]Binding ViewModel to BindingContext
有一個使用 ViewModel 顯示數據的模板。
BaseTabView.xaml
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Oss.Maui.Views.Tabs.BaseTabView"
xmlns:vm="clr-namespace:Oss.ViewModels.Tabs;assembly=Oss.ViewModels"
xmlns:controls="clr-namespace:Oss.Maui.Controls;assembly=Oss.Maui.Controls"
x:DataType="vm:BaseTabViewModel">
<ContentPage.Content>
<controls:HybridWebView x:Name="HybridView" Url="{Binding Url}" Source="{Binding Url}" LocalStoragesValue="{Binding LocalStorage}" />
</ContentPage.Content>
</ContentPage>
BaseTabView.xaml.cs
public partial class BaseTabView : ContentPage
{
public BaseTabView()
{
InitializeComponent();
#if ANDROID
HybridView.JsBridge = ServiceLocator.GetService<IJsBridge<IOssAction>>();
#endif
}
protected override void OnBindingContextChanged()
{
base.OnBindingContextChanged();
}
}
用於顯示的基本 ViewModel
public class BaseTabViewModel : ViewModel
{
protected readonly IMauiApplicationViewModel MauiApplicationViewModel;
public BaseTabViewModel(IApplication application, IMauiApplicationViewModel mauiApplicationViewModel)
: base(application)
{
MauiApplicationViewModel = mauiApplicationViewModel;
LocalStorage = new Dictionary<string, string>()
{
{"oss.locale", $"\"{mauiApplicationViewModel.PersonalSettings.CurrentCulture.TwoLetterISOLanguageName}\""},
{"hideNavbar", "true" },
{"user_account_info", "{\"displayName\":\""+mauiApplicationViewModel.UserAccount.DisplayName+"\"," +
"\"employeeId\":"+mauiApplicationViewModel.UserAccount.EmployeeId+"," +
"\"employeeName\":\""+mauiApplicationViewModel.UserAccount.EmployeeName+"\"," +
"\"expires\":\""+mauiApplicationViewModel.UserAccount.TokenDateExpiration.ToString("o")+"\"," +
"\"token\":\""+mauiApplicationViewModel.UserAccount.AccessToken+"\"," +
"\"settings\":"+mauiApplicationViewModel.UserAccount.Settings+"}"},
};
}
public string? Url { get; protected set; }
public Dictionary<string, string> LocalStorage { get; }
}
protected override void OnConnected(EventArgs e)
{
base.OnConnected(e);
UserAccount = _request.Result;
TaskTabViewModel = ScopedServices.GetRequiredService<TaskTabViewModel>();
SearchTaskTabViewModel = ScopedServices.GetRequiredService<SearchTaskTabViewModel>();
//TODO: add other tabs
Application.Messenger.Send(NavigationMessangerPage.Home);
}
授權后,我創建 ViewModels 實例。 首次渲染 MainPage 時,這些 ViewModel==null。 接下來,發生通知並計算出 OnPropertyChange(nameof(TaskTabViewModel))。 但是與非空元素的綁定在通知后不會改變。 base.OnBindingContextChanged(); 僅在第一次渲染時觸發。
<Shell xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:Oss.Maui"
xmlns:sys="clr-namespace:System;assembly=netstandard"
x:Class="Oss.Maui.MainPage"
xmlns:res="clr-namespace:Oss.Localization;assembly=Oss.Localization"
xmlns:controls="clr-namespace:Oss.Maui.Controls;assembly=Oss.Maui.Controls"
xmlns:loginView="clr-namespace:Oss.Maui.Views.Logins;assembly=Oss.Maui.Views"
xmlns:templateView="clr-namespace:Oss.Maui.Views.Tabs;assembly=Oss.Maui.Views"
xmlns:vm="clr-namespace:Oss.ViewModels;assembly=Oss.ViewModels"
Shell.NavBarIsVisible="True"
Shell.TabBarIsVisible="False"
Shell.TitleColor="Transparent"
Shell.NavBarHasShadow="False"
x:DataType="vm:MauApplicationViewModel"
BackgroundColor="{DynamicResource PageBackgroundColor}">
<ShellItem Route="login" FlyoutItemIsVisible="False">
<ShellContent ContentTemplate="{DataTemplate loginView:LoginView}"/>
</ShellItem>
<FlyoutItem Route="main" FlyoutDisplayOptions="AsMultipleItems">
<ShellContent Title="{res:Translate TaskTabTitle}" Icon="home.png">
<templateView:BaseTabView BindingContext="{Binding TaskTabViewModel, Mode=TwoWay}"></templateView:BaseTabView>
</ShellContent>
<ShellContent Title="{res:Translate SearchTaskTabTitle}" Icon="list.png">
<templateView:BaseTabView BindingContext="{Binding SearchTaskTabViewModel, Mode=TwoWay}"></templateView:BaseTabView>
</ShellContent>
</FlyoutItem>
</Shell>
如何僅在授權后顯示選項卡或更新綁定?
更新:
廣告任務TabViewModel
private TaskTabViewModel _taskTabViewModel;
public TaskTabViewModel TaskTabViewModel
{
get => _taskTabViewModel;
set
{
SetValue(ref _taskTabViewModel, value);
}
}
ViewModel.SetValue
protected bool SetValue<T>(ref T property, T value, [CallerMemberName] string propertyName = null)
{
return SetValue(ref property, value, propertyName, null);
}
protected bool SetValue<T>(ref T property, T value, string propertyName, Action action)
{
if (Equals(property, value))
return false;
property = value;
NotifyPropertyChanged(propertyName);
if (action != null)
action();
return true;
}
我不能確保問題是 PropertyChangedEventHandler 是否可以用於內容頁面的綁定上下文。 但是我查了源碼,發現頁面中只有一個名為ContentProperty的BindableProperty。 所以綁定上下文不是可綁定的屬性。
如果要在獲取 viewmodel 的實例后設置 BaseTabView 的綁定上下文。 你可以試試下面的代碼。
TaskTabViewModel = ScopedServices.GetRequiredService<TaskTabViewModel>();
Shell.Current.Items[1].Items[0].BindingContext = TaskTabViewModel;
// the first Items is flyoutitem which route is main and the second items is the BaseTabView
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.