简体   繁体   English

将代码隐藏的定义属性绑定到XAML中的DataContext属性?

[英]Binding a code-behind defined property to a DataContext property in XAML?

I'm trying to bind a property that was defined in Page code-behind to a ListView.DataContext property in XAML, but for some reason it's not working in the way that I thought, when I run the app the ListView.DataContext is not being set and remains null, can someone please help me with that? 我正在尝试将在页面代码中定义的属性绑定到XAML中的ListView.DataContext属性,但是由于某种原因,它无法按照我认为的方式工作,因此当我运行该应用程序时,ListView.DataContext并没有被设置并保持为空,有人可以帮我吗?

I looked for some similar questions but most of them solve the problem by setting the DataContext manually in the code-behind, but I'd like to do that from XAML. 我寻找了一些类似的问题,但是大多数问题是通过在代码背后手动设置DataContext来解决的,但是我想从XAML做到这一点。

MainPage.xaml MainPage.xaml

<Page
    x:Class="CustomControls.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:CustomControls"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <StackPanel>
        <ListView
            DataContext="{Binding Path=MyMarket, RelativeSource={RelativeSource Mode=Self}}"
            ItemsSource="{Binding Path=Products}"
            Header="{Binding Path=Name}">

            <ListView.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <TextBlock Text="{Binding Path=Id}"/>
                        <TextBlock Text="{Binding Path=Description}"/>
                    </StackPanel>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackPanel>
</Page>

MainPage.xaml.cs MainPage.xaml.cs

using System.Collections.ObjectModel;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;

namespace CustomControls
{
    public sealed partial class MainPage : Page
    {
        public Market MyMarket { get; private set; }

        public MainPage()
        {
            this.InitializeComponent();

            this.NavigationCacheMode = NavigationCacheMode.Required;

            this.MyMarket = new Market
            {
                Name = "My Market",
                Products = new ObservableCollection<Product>
                {
                    new Product { Id = 123, Description = "qwerty" },
                    new Product { Id = 234, Description = "wertyu" }
                }
            };
        }
    }

    public class Product
    {
        public int Id { get; set; }
        public string Description { get; set; }
    }

    public class Market
    {
        public string Name { get; set; }
        public ObservableCollection<Product> Products { get; set; }
    }
}

{RelativeSource Mode=Self} refers to the current element, in this case ListView , so it's not what you want. {RelativeSource Mode=Self}引用当前元素,在本例中为ListView ,所以它不是您想要的。 The easiest way is to give a name to the root element (the Page ), for instance "root" , and specify ElementName=root in your binding. 最简单的方法是为根元素( Page )命名,例如"root" ,并在绑定中指定ElementName=root

You have to bind to the page, so you have to do that at the very top of your XAML: 您必须绑定到页面,因此必须在XAML的最顶部执行此操作:

<Page
[..]
DataContext="{Binding MyMarket, RelativeSource={RelativeSource Self}}">

Then you should be able to hook into that like this: 然后,您应该可以像下面这样:

<ListView
    ItemsSource="{Binding Path=Products}"
    Header="{Binding Path=Name}">
[..]

Now just switch the lines in your constructor so that your elements are already there before the page is built: 现在,只需在构造函数中切换行,以使您的元素在构建页面之前就已经存在:

this.MyMarket = new Market
{
    Name = "My Market",
    Products = new ObservableCollection<Product>
    {
        new Product { Id = 123, Description = "qwerty" },
        new Product { Id = 234, Description = "wertyu" }
    }
};
this.InitializeComponent();

this.NavigationCacheMode = NavigationCacheMode.Required;

You should consider using Viewmodel classes later on. 您应该稍后再考虑使用Viewmodel类。

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

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