Xaml Xamarin:通过代码隐藏中的引用设置多个viewmodels
我需要根据xaml代码中的代码设置两个ViewModels。或者,如果有更好的方式做,将是伟大的 当我这样做的时候,应用程序崩溃了。当我在代码隐藏(BindingContext=ViewModel)中设置ProductDetailViewModel时,一切正常 更新 将viewModels作为参数传递不是一个好主意。 我现在有一个类“ViewModelLocator”,它包含所有作为静态属性的ViewModels。使用谷歌获取更多信息。这样事情就容易多了 范例 视图模型定位器Xaml Xamarin:通过代码隐藏中的引用设置多个viewmodels,xaml,xamarin,xamarin.forms,mvvm,Xaml,Xamarin,Xamarin.forms,Mvvm,我需要根据xaml代码中的代码设置两个ViewModels。或者,如果有更好的方式做,将是伟大的 当我这样做的时候,应用程序崩溃了。当我在代码隐藏(BindingContext=ViewModel)中设置ProductDetailViewModel时,一切正常 更新 将viewModels作为参数传递不是一个好主意。 我现在有一个类“ViewModelLocator”,它包含所有作为静态属性的ViewModels。使用谷歌获取更多信息。这样事情就容易多了 范例 视图模型定位器 public st
public static class ViewModelLocator
{
public static AddProductViewModel AddProductViewModel { get; set; } = new AddProductViewModel(App.ProductDataStore, App.NavigationService);
}
结束更新
更新2
**Xamarin.Forms.Xaml.XamlParseException:** 'Position 9:10. Can not find the object referenced by `ProductDetailViewModel`'
正如@Waescher所说,最好使用FreshMvvm。静态方法简单快速,但不适合速度较慢的设备或更大的应用程序。谢谢
结束更新2
**Xamarin.Forms.Xaml.XamlParseException:** 'Position 9:10. Can not find the object referenced by `ProductDetailViewModel`'
因为我不能直接在xaml中设置ViewModels,所以我需要从代码隐藏中引用它
请参见xaml代码中的<***第一视图模型***>和<***第二视图模型***>
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:controls="clr-namespace:BoerPlaza.Controls"
xmlns:flv="clr-namespace:DLToolkit.Forms.Controls;assembly=DLToolkit.Forms.Controls.FlowListView"
xmlns:ffimageloading="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms"
x:Class="BoerPlaza.Views.Product.ProductCustomerPictures">
<ContentPage.BindingContext>
<x:Reference Name="ProductDetailViewModel" /><!-- *** First ViewModel ***!-->
</ContentPage.BindingContext>
<ContentPage.Content>
<StackLayout>
<!-- Total image count -->
<Label Text="{Binding Product.UserImages.Total}"
Style="{StaticResource H2}" />
<!-- Title -->
<Label Text="{Binding Product.Title}"
Style="{StaticResource H1}" />
<!-- reviews -->
<StackLayout Orientation="Horizontal">
<controls:StarDisplayTemplateView x:Name="customRattingBar"
SelectedStarValue="{Binding Product.RatingTotal}" />
<Label Text="{Binding Product.RatingAmount, StringFormat='{0} reviews | '}" />
<Label Text="Schrijf een review" />
</StackLayout>
<Label Text="{Binding Product.Title, StringFormat='Heb je een productfoto van {0} die je wilt delen? '}" />
<Button Text="Foto's toevoegen"
Command="{Binding SelectImagesCommand}"
BackgroundColor="{StaticResource neutral-color}"
BorderColor="{StaticResource alt-color}"
BorderWidth="1"
TextColor="{StaticResource primary-color}"
HorizontalOptions="Start"
HeightRequest="40"
FontSize="12" />
<!-- hr -->
<BoxView Style="{StaticResource separator}" />
<flv:FlowListView FlowColumnCount="3"
x:Name="listItems"
FlowItemsSource="{Binding Media}"
SeparatorVisibility="None"
HasUnevenRows="false"
RowHeight="100"
HeightRequest="0">
<flv:FlowListView.BindingContext>
<x:Reference Name="MultiMediaPickerViewModel" /> <!-- *** Second ViewModel ***!-->
</flv:FlowListView.BindingContext>
<flv:FlowListView.FlowColumnTemplate>
<DataTemplate>
<Grid>
<ffimageloading:CachedImage DownsampleToViewSize="true"
HeightRequest="100"
Source="{Binding PreviewPath}"
Aspect="AspectFill"
HorizontalOptions="FillAndExpand">
</ffimageloading:CachedImage>
<Image Source="play"
IsVisible="false"
HorizontalOptions="End"
VerticalOptions="End">
<Image.Triggers>
<DataTrigger TargetType="Image"
Binding="{Binding Type}"
Value="Video">
<Setter Property="IsVisible"
Value="True" />
</DataTrigger>
</Image.Triggers>
</Image>
</Grid>
</DataTemplate>
</flv:FlowListView.FlowColumnTemplate>
</flv:FlowListView>
</StackLayout>
</ContentPage.Content>
</ContentPage>
如果我正确理解了这一点,并且希望将模式作为构造函数参数传递到视图模型中
public ProductCustomerPictures(ProductDetailViewModel viewModel)
{
InitializeComponent();
ProductDetailViewModel = viewModel;
MultiMediaPickerViewModel = new MultiMediaPickerViewModel(MultiMediaPickerServiceStaticVariableHolder.MultiMediaPickerService);
}
。。。然后你可以完全移除这个
<ContentPage.BindingContext>
...
</ContentPage.BindingContext>
相反,只需直接在构造函数中设置BindingContext
public ProductCustomerPictures(ProductDetailViewModel viewModel)
{
InitializeComponent();
BindingContext = viewModel; // <-- here
MultiMediaPickerViewModel = new MultiMediaPickerViewModel(MultiMediaPickerServiceStaticVariableHolder.MultiMediaPickerService);
}
现在,您可以在绑定表达式中使用名称作为引用:
<flv:FlowListView FlowColumnCount="3"
x:Name="listItems"
FlowItemsSource="{Binding Source={x:Reference thisPage}, Path=MultiMediaPickerViewModel.Media}"
SeparatorVisibility="None"
HasUnevenRows="false"
RowHeight="100"
HeightRequest="0">
顺便说一下,您可以压缩代码中的属性:
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class ProductCustomerPictures : ContentPage
{
public ProductDetailViewModel ProductDetailViewModel
{
get { return _productDetailViewModel; }
set { _productDetailViewModel = value; }
}
public MultiMediaPickerViewModel MultiMediaPickerViewModel
{
get { return _multiMediaPickerViewModel; }
set { _multiMediaPickerViewModel = value; }
}
private ProductDetailViewModel _productDetailViewModel;
private MultiMediaPickerViewModel _multiMediaPickerViewModel;
public ProductCustomerPictures(ProductDetailViewModel viewModel)
{
InitializeComponent();
ProductDetailViewModel = viewModel;
MultiMediaPickerViewModel = new MultiMediaPickerViewModel(MultiMediaPickerServiceStaticVariableHolder.MultiMediaPickerService);
}
}
public MultiMediaPickerViewModel MultiMediaPickerViewModel { get; private set; }
public ProductCustomerPictures(ProductDetailViewModel viewModel)
{
InitializeComponent();
BindingContext = viewModel;
MultiMediaPickerViewModel = new MultiMediaPickerViewModel(MultiMediaPickerServiceStaticVariableHolder.MultiMediaPickerService);
}
为什么您认为不能在XAML中设置它?这是什么
ProductDetailViewModel
?它来自哪里?从前面的观点来看。当我这样做时,应用程序崩溃。当我在代码中设置ProductDetailViewModel时,一切正常。只需一次更新。将viewModels作为参数传递不是一个好主意。我现在有一个类“ViewModelLocator”,它将所有ViewModels作为静态属性。我在AppShell.xaml中初始化它们。使用谷歌获取更多信息。如果你想听听我的意见:不要把viewModels作为参数传递,也不要使用静态方法。ViewModels可能会占用大量内存。不要使用“视图到视图”导航,而是使用“视图模型到视图模型”导航。有了这个,你可以很容易地用IoC容器连接起来。帮自己一个忙,检查一下FreshMvvm。
<flv:FlowListView.BindingContext>
...
</flv:FlowListView.BindingContext>
public MultiMediaPickerViewModel MultiMediaPickerViewModel { get; private set; }
public ProductCustomerPictures(ProductDetailViewModel viewModel)
{
InitializeComponent();
BindingContext = viewModel;
MultiMediaPickerViewModel = new MultiMediaPickerViewModel(MultiMediaPickerServiceStaticVariableHolder.MultiMediaPickerService);
}