在 Xamarin 中将页面绑定上下文设置为不同的视图模型时如何将控件绑定到视图模型

问题描述

我的内容页面绑定到一个视图模型,但现在我需要将一些组件绑定到一个不同的视图模型。我的问题是,因为我已将页面的 BindingContext 绑定到视图模型,当我尝试将元素绑定到第二个视图模型时,{Binding propertyname} 语句在视图模型中查找属性绑定到 bindingcontext。

所以我的问题是:当 bindingcontext 设置为不同的视图模型时,如何简单地将元素绑定到视图模型而不是绑定上下文?

我尝试过但没用的东西

  1. 定义了第二个视图模型。并尝试通过静态资源绑定

代码

    <ContentPage.Resources>
        <ResourceDictionary>
            <selectedDeal:DealsMviewmodel x:Name="SelectedDeal" x:Key="SelectedDeal"/>
        </ResourceDictionary>
    </ContentPage.Resources>

代码

 <Image
     x:Name="CompanyImage"
     HeightRequest="200"
     Aspect="AspectFill"
     Source="{Binding Source={StaticResource SelectedDeal},Path=DealImage}" />
  1. 我已将图像元素放入堆栈布局,设置 StackLayout 的 BindingContext 并 尝试这样绑定:

代码

 <Image
         x:Name="CompanyImage"
         HeightRequest="200"
         Aspect="AspectFill"
         Source="{Binding DealImage}"/>
     

我有两种方法使绑定工作

  1. 将第二个视图模型定义为绑定到 BindingContext 的第一个视图模型的属性,然后像这样实现图像

代码

<Image
x:Name="CompanyImage"
HeightRequest="200"
Aspect="AspectFill"
Source="{Binding secondviewmodel.DealImage}"/>
  1. 在后面的代码中以编程方式设置图像源。

代码

CompanyImage.source = selectedDeal.DealImage;

但我真正想要实现的是尽可能在 XAML 部分学习这样做的方法!非常感谢任何帮助!

解决方法

有几种方法可以实现您的要求...我将解释我处理 ViewModel 绑定的方式...

  1. 使用 DependencyService 容器管理器创建新类以保存对每个视图模型的引用。我称之为 ViewModelLocator。例如:
public class ViewModelLocator
    {
        public ViewModelLocator()
        {
            DependencyService.Register<ILogService,LogService>();
            if (!DesignMode.IsDesignModeEnabled)
            {
                DependencyService.Register<IDataStore,MockDataStore>();
            }
            else
            {
                DependencyService.Register<IDataStore,DesignDataStore>();
            }
            DependencyService.Register<LoginViewModel>();
            DependencyService.Register<AboutViewModel>();
            DependencyService.Register<SettingsViewModel>();
        }
        public LoginViewModel Login => DependencyService.Get<LoginViewModel>();
        public AboutViewModel About => DependencyService.Get<AboutViewModel>();
        public SettingsViewModel Settings => DependencyService.Get<SettingsViewModel>();
    }
  1. 在你的 App.xaml 中引用这个类

  2. 这将允许您仅通过引用定位器来绑定到任何视图模型。 在下面的示例中,您的“主要”ViewModel 是 LoginViewModel,但下面的按钮绑定到 About ViewModel

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Test.Views.LoginPage"
             BindingContext="{Binding Login,Source={StaticResource Locator}}"
             Title="LoginPage">
    <ScrollView>
        <Grid Margin="10,20,10,10" RowDefinitions="Auto,Auto,Auto">
            <Label Grid.Row="0" Text="Username:" TextColor="Black" FontSize="14"/>
            <Entry Grid.Row="1" x:Name="usernameEditor" Text="{Binding Username}" ClearButtonVisibility="WhileEditing" />
            <Label Grid.Row="2" Text="Password:" TextColor="Black" FontSize="14"/>
            <Entry Grid.Row="3" x:Name="passwordEditor" Text="{Binding Password}" IsPassword="True" ClearButtonVisibility="WhileEditing" />
            <Button Grid.Row="6" Text="Login" Command="{Binding About.LoginCommand,Source={StaticResource Locator}}"/>
        </Grid>
    </ScrollView>
</ContentPage>