简体   繁体   English

如何将ViewModel绑定到另一个XAML文件的ListView中的XAML文件?

[英]How can I bind a ViewModel to an XAML file inside a ListView of another XAML file?

I genuinely was unsure how to search for this, so I'm hoping someone can understand my problem and either help or clarify if my approach is incorrect. 我确实不确定该如何搜索,所以我希望有人可以理解我的问题,并帮助或阐明我的方法是否不正确。

I have 2 XAML files ( ItemsPage and ItemTemplatePage ) and I'm wanting to bind each XAML file to a ViewModel ( ItemsPageViewModel and ItemTemplateViewModel ) - now this is simple when they're both separate pages, but in this example ItemTemplatePage is loaded inside a ListView on the ItemsPage for every Item in Items. 我有2个XAML文件( ItemsPageItemTemplatePage ),我想将每个XAML文件绑定到ViewModel( ItemsPageViewModelItemTemplateViewModel )-现在,当它们都是单独的页面时,这很简单,但是在此示例中,ItemTemplatePage加载到ItemsItem中每个项目的ItemsPage上的ListView。

Obviously when I interact with an Item I will call the code behind for ItemTemplatePage but instead I would rather call a Command for ItemTemplateViewModel. 显然,当我与Item交互时,我将在后面为ItemTemplatePage调用代码,但我宁愿为ItemTemplateViewModel调用Command。 However, when Items populate and bind to the ListViews ItemsSource in the ItemsPage, from what I understand that creates a BindingContext of Item for that specific template. 但是,当Items填充并绑定到ItemsPage中的ListViews ItemsSource时,据我了解,这会为该特定模板创建Item的BindingContext。 So it's not like I can call in the constructor for ItemTemplatePage: 因此,这不像我可以在ItemTemplatePage的构造函数中调用的那样:

BindingContext = new ItemTemplateViewModel();

Because at this point it overwrites any binding done by ItemsSource from the ItemsPage; 因为此时它会覆盖ItemsSource从ItemsPage完成的所有绑定; least that's what I've experienced so far. 至少那是我到目前为止所经历的。

Below is the code I have so far to provide an understanding from a code point of view, is what I'm trying to achieve doable or am I making it to complex for myself or have I misunderstand Binding and my approach is completely wrong? 下面是到目前为止我可以从代码的角度理解的代码,是我试图实现可行的代码,还是让我自己变得复杂,或者我误解了Binding,而我的方法是完全错误的?

Any and all help is highly appreciated! 任何帮助都将受到高度赞赏!

=== ===

ItemsPage.xaml ItemsPage.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:template="clr-namespace:App.Views.Templates"
             x:Class="App.Views.ItemsPage"
             Title="All Items">
    <ContentPage.Content>
        <StackLayout>
            <ListView ItemsSource="{Binding Items}">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell>
                            <template:Item />
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </StackLayout>
    </ContentPage.Contant>
</ContentPage>

ItemsPage.xaml.cs ItemsPage.xaml.cs

Public ItemsPage() {
    InitializeComponent();
    BindingContext = new ItemsPageViewModel();
}

ItemsPageViewModel.cs ItemsPageViewModel.cs

public class ItemsPageViewModel : BaseViewModel {
    private ObservableCollection<Item> items;
    public ObservableCollection<Item> Items { get => items; set => SetValue(ref items, value); }

    public ItemsPageViewModel() => DownloadItems();

    private async void Download() => Items = await API.GetItems(); 
}

ItemTemplagePage.xaml ItemTemplagePage.xaml

<?xml version="1.0" encoding="utf-8" ?>
<StackLayout xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             x:Class="App.Views.Templates.ItemTemplatePage"
             Spacing="0">
     <Label Text="{Binding Name}" />
     <Button Text="View" />
</StackLayout>

I've not provided the code behind for ItemTemplatePage.xaml because there is no additional code written here. 我没有提供ItemTemplatePage.xaml的代码,因为这里没有编写其他代码。

ListView implements DataTemplate , which means that its contents are bound to the item, not to the page view model in general and that's how it should work, if you try to provide any other binding context it won't crash the app, but for sure app won't work as expected as you basically act against the logic of XAML that way. ListView实现DataTemplate ,这意味着它的内容绑定到项目,而不是一般地绑定到页面视图模型,这就是它应该工作的方式,如果您尝试提供任何其他绑定上下文,它不会使应用程序崩溃,但是可以肯定应用程序将无法正常运行,因为您基本上会以这种方式违反XAML逻辑。

Also your ItemTemplagePage is not a page at all (and shouldn't be), but for some reason you call it a page and that probably confuses you further. 同样,您的ItemTemplagePage根本不是(也不应该是)页面,但是由于某种原因,您将其称为页面,这可能会使您进一步困惑。

Overall you need to work more to understand some basic terms and principles in XAML. 总的来说,您需要做更多的工作才能了解XAML中的一些基本术语和原理。 I guess that you wanted to check if that's correct and that's fine. 我想您想检查是否正确,这很好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM