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

时间:2014-10-18 22:52:45

标签: c# xaml windows-runtime

我试图将在页面代码隐藏中定义的属性绑定到XAML中的ListView.DataContext属性,但由于某种原因,它不按我想象的方式工作,当我运行应用程序ListView.DataContext没有设置并保持为空,有人可以帮我吗?

我找了一些类似的问题但是大多数问题都是通过在代码隐藏中手动设置DataContext来解决问题,但是我想从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中

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; }
    }
}

2 个答案:

答案 0 :(得分:1)

{RelativeSource Mode=Self}引用当前元素,在本例中为ListView,因此它不是您想要的。最简单的方法是为根元素(Page)命名,例如"root",并在绑定中指定ElementName=root

答案 1 :(得分:1)

您必须绑定到该页面,因此您必须在XAML的最顶层执行此操作:

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

然后你应该能够像这样挂钩:

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

现在只需在构造函数中切换行,以便在构建页面之前元素已经存在:

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;

您应该考虑稍后使用Viewmodel类。