【问题标题】:How can I bind a ViewModel to an XAML file inside a ListView of another XAML file?如何将 ViewModel 绑定到另一个 XAML 文件的 ListView 内的 XAML 文件?
【发布时间】:2019-07-24 10:30:35
【问题描述】:

我真的不确定如何搜索这个,所以我希望有人能理解我的问题,并帮助或澄清我的方法是否不正确。

我有 2 个 XAML 文件(ItemsPageItemTemplatePage),我想将每个 XAML 文件绑定到一个 ViewModel(ItemsPageViewModelItemTemplateViewModel) - 现在,当它们都是单独的页面时,这很简单,但在此示例中,ItemTemplatePage 被加载到 ItemsPage 上的 ListView 中,用于 Items 中的每个项目。

显然,当我与一个项目交互时,我会为 ItemTemplatePage 调用后面的代码,但我宁愿为 ItemTemplateViewModel 调用一个命令。但是,当 Items 填充并绑定到 ItemsPage 中的 ListViews ItemsSource 时,据我所知,它会为该特定模板创建 Item 的 BindingContext。所以我不能在 ItemTemplatePage 的构造函数中调用:

BindingContext = new ItemTemplateViewModel();

因为此时它会覆盖 ItemsSource 从 ItemsPage 完成的任何绑定;至少这是我迄今为止所经历的。

以下是迄今为止我从代码的角度提供理解的代码,是我试图实现的目标,还是我自己让它变得复杂,或者我误解了绑定,我的方法是完全错了吗?

非常感谢任何和所有帮助!

===

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

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

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

<?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>

我没有提供 ItemTemplatePage.xaml 背后的代码,因为这里没有编写额外的代码。

【问题讨论】:

    标签: c# xaml listview xamarin xamarin.forms


    【解决方案1】:

    ListView 实现DataTemplate,这意味着它的内容绑定到项目,而不是一般的页面视图模型,这就是它应该如何工作,如果你尝试提供任何其他绑定上下文它不会使应用程序崩溃,但可以肯定的是,应用程序不会按预期工作,因为您基本上以这种方式违反了 XAML 的逻辑。

    此外,您的 ItemTemplagePage 根本不是页面(也不应该是),但出于某种原因,您将其称为页面,这可能会让您更加困惑。

    总的来说,您需要做更多的工作来理解 XAML 中的一些基本术语和原则。我猜你想检查这是否正确,这很好。

    【讨论】:

    • 感谢您对伊万的理解,从您的解释来看,我的方法似乎不可行。所以这意味着我需要将 ItemTemplatePage 的代码隐藏用于任何业务逻辑?当您提到 ItemTemplatePage 不是实际页面时,我相信我了解您的来源。这是因为它不是根标签是 而是 ?我采用这种方法,认为在其中加载第二个 是没有意义的,我的想法是否正确?
    • @MattVon 很难/不可能在一个答案中解释多个基本概念。但是是的,ItemTemplatePage 不能有自己的视图模型。如果你真的需要在数据模型中放置一些逻辑,你可以在其中放置一些逻辑,它感觉最接近你的要求。
    猜你喜欢
    • 2017-12-14
    • 1970-01-01
    • 2016-10-14
    • 2012-08-15
    • 1970-01-01
    • 2013-02-11
    • 1970-01-01
    • 2014-01-10
    • 2017-01-23
    相关资源
    最近更新 更多