ListBox ItemTemplate与CLR和UserControl数据相互矛盾

时间:2010-07-22 02:19:51

标签: c# wpf data-binding listbox itemtemplate

我为我的应用程序编写了一个简单的UpDown UserControl。我在ListBox中渲染它,以便在添加UpDown控件时,它们会水平堆叠。

我的UserControl有一个DependencyProperty,对应于UpDown控件内部的数字,称为NumberProperty。

我通过数据绑定向ListBox添加了多个UpDown控件,其中ListBox的ItemsSource只是一个名为ObservableCollection<NumberGroup>的{​​{1}}。每个NumberGroups只有一个名为Number的成员,我希望在呈现ListBox时该数字出现在其各自的UpDown控件中。

我的ListBox在XAML中定义如下:

NumberGroup

和ListBox的DataTemplate是:

    <ListBox Grid.Row="1" ItemsSource="{Binding NumberGroups}" ItemTemplate="{StaticResource NumberGroupTemplate}">
        <ListBox.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel Orientation="Horizontal" Width="Auto" Height="Auto" />
            </ItemsPanelTemplate>
        </ListBox.ItemsPanel>
    </ListBox>

这有点令人困惑,因为我在UpDown UserControl中将DependencyProperty <DataTemplate x:Key="RackTemplate"> <StackPanel Orientation="Vertical"> <TextBlock>Group</TextBlock> <updown:UpDown Number="{Binding Number}" /> </StackPanel> </DataTemplate> 命名为与NumberGroup类中的属性相同。 NumberGroup仅仅是:

Number

当我运行应用程序时,我已经知道它不会起作用,因为“输出”窗口告诉我:

public class NumberGroup
{
    public int Number { get; set; }
}

好的,所以它绑定到UserControl而不是ListItem ......无法写入。因此,作为测试,我从Resources和ListBox定义中删除了DataTemplate并重新运行它。在ListBox中,我得到了一堆System.Windows.Data Error: 39 : BindingExpression path error: 'Number' property not found on 'object' ''UpDown' (Name='')'. BindingExpression:Path=Number; DataItem='UpDown' (Name=''); target element is 'UpDown' (Name=''); target property is 'Number' (type 'Int32') s,这正是我所期待的!

那么当我这样做时,它似乎与ListItem绑定,但是当我定义ItemTemplate时它想要绑定到UpDown控件?任何解释都会非常感激。我已经阅读了WPF博士的文章,并且不明白为什么会发生这种情况。

更新

好的,我想出了与我的问题有关的事情。在UserControl中,我将DataContext设置为自身,以便我可以处理处理Up和Down按钮的NumberGroup。但由于某些原因我还不明白,它与ListItem的数据绑定混淆了!如果UserControl包含在ListItem中,为什么会发生这种情况?

1 个答案:

答案 0 :(得分:1)

当您将UserControl的DataContext内部设置为自身时,您获得的效果与执行此操作完全相同:

<updown:UpDown DataContext="{Binding RelativeSource={RelativeSource Self}}" />

显然现在你设置的没有明确Source定义的任何Bindings都会使用UpDown控件作为它们的上下文。因此,当您尝试绑定到Number属性时,它正在UpDown上寻找Number属性而不是ListBoxItem的数据。这正是您的错误告诉您的。

要避免这种情况,请将UserControl中的DataContext设置更改为应用于控件内的元素,例如带有x:Name的根布局Grid。

<Grid x:Name="LayoutRoot">
...
</Grid>

并在代码或XAML中设置DataContext。

LayoutRoot.DataContext = this;