[英]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做到这一点。
<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>
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.