对代码隐藏类属性集合的XAML绑定为空(WPF)

时间:2016-09-20 14:29:26

标签: c# wpf xaml

我的代码隐藏定义了一个带有属性和构造函数的简单类,如下所示:

public class Question
{
    public string[] Answers
    {
        get; set;
    }
    public int CorrectAnswerIndex
    {
        get; set;
    }
    public Question(string[] answers, int correctIndex)
    {
        this.Answers = answers;
        this.CorrectAnswerIndex = correctIndex;
    }
}

然后存在一个这种类型的公共对象,它在窗口的构造函数中初始化,如下所示:

 CurrentQuestion = new Question(
     new string[] { "First", "Second", "Third", "Fourth" }, 2
 );

然后我有以下XAML试图从所述问题中打印出所有可能的答案。

<Grid Margin="150,150,150,150" DataContext="local:CurrentQuestion">
        <ListBox ItemsSource="{Binding Answers}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{Binding}" />
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
</Grid>

本地名称空间以前被定义为CLR名称空间。

然而,我的名单显得空洞无物。运行时没有绑定错误。

这里发生了什么?这似乎是一个简单的例子,只是不会运行。我觉得我错过了一些“明显的东西”。

1 个答案:

答案 0 :(得分:2)

对于名为ListBox.DataContext的属性,我们会查看Answers,并尝试将其用于ItemsSource

<ListBox ItemsSource="{Binding Answers}">

ListBox.DataContext将从父Grid继承。不幸的是,网格的DataContext是一个字符串,字符串没有名为Answers的属性。因此Binding无法执行任何操作并为您提供null

<Grid Margin="150,150,150,150" DataContext="local:CurrentQuestion">
    <ListBox ItemsSource="{Binding Answers}">

XAML隐式转换是Do-What-I-Mean的事情,因此是一个混乱的源头。有时您可以将local:CurrentQuestion放在属性值中并将其作为数据类型 - 但这不是其中之一。并且数据类型不是您想要提供的。你想要一个名字的财产。但是local:是一个名称空间,一个像System.Windows.Controls这样的文字CLR名称空间,而不是对象的引用。

以下是UserControl中的XAML如何绑定到UserControl的属性。如果是Window,请将UserControl更改为Window

<Grid Margin="150,150,150,150">
    <ListBox 
        ItemsSource="{Binding CurrentQuestion.Answers, RelativeSource={RelativeSource AncestorType=UserControl}}">

我只是猜测CurrentQuestionUserControl的属性。如果它在其他地方,请告诉我。

更新CurrentQuestion时,您可能还会遇到问题,除非它是依赖属性。如果它是这样的普通旧CLR属性,则在其值更改时不会通知UI:

public Question CurrentQuestion { get; set; }