【问题标题】:WPF: ItemsControl and DataContextWPF:ItemsControl 和 DataContext
【发布时间】:2011-01-14 10:26:55
【问题描述】:

我有一个主窗口,其中有一个用户控件,称为SuperModeSuperMode 由一群人组成,这个集合中的每个人都有自己的任务集合。听起来很简单,对吧?

来自文件SuperMode.xaml

<UserControl 
    x:Class="Prototype.SuperMode"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:Prototype"
    DataContext="{Binding RelativeSource={RelativeSource Self}}"> <!-- NOTE! -->
    <!-- Look at how I'm setting the DataContext, as I think it's
         important to solve the problem! -->

    <ScrollViewer CanContentScroll="True">
        <ItemsControl ItemsSource="{Binding People}" Margin="1">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <UniformGrid Rows="1"/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
        </ItemsControl>
    </ScrollViewer>

</UserControl>

这很好,我可以看到 四个 人,正如我所期望的那样!现在我所要做的就是为 Person 用户控件设置 XAML 权限,以便他们的所有任务也能显示出来。

如您所见,我正在使用People 属性为控件填充项目。 People 属性的类型为 ObservableCollection&lt;Person&gt;,其中 Person 是另一个用户控件,因此...

来自Person.xaml

<UserControl 
    x:Class="Prototype.Person"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:Prototype">

    <Border Background="Black" CornerRadius="4" Margin="1">
        <ItemsControl ItemsSource="{Binding Tasks}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
        </ItemsControl>
    </Border>

</UserControl>

Tasks 这里是Person 类型为ObservableCollection&lt;Task&gt; 的属性。这就是卡住的地方!显然 WPF 找不到任何 Tasks 属性并查看 VS2008 的输出窗口,我发现以下内容:

System.Windows.Data 错误:39:BindingExpression 路径错误:在“对象”“SuperMode”(名称=“SuperMode”)上找不到“Tasks”属性。绑定表达式:路径=任务; DataItem='SuperMode'(名称='SuperMode');目标元素是'ItemsControl'(名称='');目标属性是“ItemsSource”(类型“IEnumerable”)

现在我迷路了。看来我必须在每个Person上设置DataContext属性,否则它仍然会认为数据上下文是SuperMode,但是我该怎么做呢?

【问题讨论】:

    标签: c# wpf datacontext itemscontrol


    【解决方案1】:

    忽略您拥有的相当不愉快的设计(您应该查看 MVVM),您应该能够为子 UserControls 设置 DataContext,如下所示:

    <ItemsControl ItemsSource="{Binding People}" Margin="1">
        <ItemsControl.ItemContainerStyle>
            <Style>
                <Setter Property="FrameworkElement.DataContext" Value="{Binding RelativeSource={RelativeSource Self}}"/>
            </Style>
        </ItemsControl.ItemContainerStyle>
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <UniformGrid Rows="1"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
    </ItemsControl>
    

    【讨论】:

    • 谢谢,我会尝试并回复您。你碰巧有一个链接到一个好地方,在那里我可以看到一个真实的 MVVM 示例,并附有源代码和解释?