簡體   English   中英

將 ViewModel 綁定到 BindingContext

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM