【问题标题】:Binding a code-behind defined property to a DataContext property in XAML?将代码隐藏定义的属性绑定到 XAML 中的 DataContext 属性?
【发布时间】:2014-10-18 22:52:44
【问题描述】:

我正在尝试将页面代码隐藏中定义的属性绑定到 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; }
    }
}

【问题讨论】:

    标签: c# xaml windows-runtime


    【解决方案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 类。

    【讨论】:

    • Fred,我刚刚尝试过,但没有成功,正如我在此评论中对另一个问题所写的那样,您有什么想法吗?我认为这将是正确的方法,即使它看起来不像那样工作。
    • 它有效。只是一个初始化缺陷。我编辑了我的答案。您也可以将 DataContext 标记留在列表视图中 - 在此解决方案中已过时。我也编辑了它。
    • Fred,你太棒了,谢谢你的回答?如果我错了,请帮我最后一个忙并纠正我,所以属性初始化必须在调用 InitializeComponent 之前完成,因为当我在 DataContext 属性已经被分配之后 MyMarket 属性还没有被实例化并且当我将这个新实例分配给它时,它不会刷新 UI 以进行更改,什么也没发生?
    • 是的,没错。该页面绑定到 MyMarket(当时为空),并且不知道您正在更改引用。
    【解决方案2】:

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

    【讨论】:

    • 好的,我将x:Name="mainPage" 添加到Page 声明中,并在ListView 声明中将asd 替换为qwe,感谢Thomas,但还有一个问题你说我不是指根元素,所以我尝试从ListView 声明中删除DataContext 属性设置,并将其添加到Page 声明中,即使它不起作用,你能解释一下吗?在最后一个上下文中,self 指的是Page,所以它不应该以同样的方式工作吗?
    猜你喜欢
    • 2011-07-04
    • 2019-06-07
    • 1970-01-01
    • 1970-01-01
    • 2010-12-16
    • 2018-12-08
    • 2013-10-17
    • 2012-01-28
    • 2016-09-05
    相关资源
    最近更新 更多