WPF - 两个相同的列表框,只显示一个

时间:2014-04-12 18:53:43

标签: wpf

那里发生了一些奇怪的

我有一个包含2个元素的水平stackpanel:两个相同的列表框。

以下是有问题的摘录:

<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:System="clr-namespace:System;assembly=mscorlib" xmlns:local="clr-namespace:Uxmal.Views" x:Class="Uxmal.Views.MainWindow"
Title="Test title">
<StackPanel Orientation="Horizontal">
<ListBox ItemsSource="{Binding TestControls, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:MainWindow}}}" />
<ListBox ItemsSource="{Binding TestControls, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:MainWindow}}}" />
</StackPanel>
</Window>

两个列表框是(或应该)绝对相同。它们绑定到相同的数据源,即用户控件的集合。

窗口的构造函数:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        testControls.Add(new XmlElementControl());
        testControls.Add(new XmlElementControl());
        testControls.Add(new XmlElementControl());
        testControls.Add(new XmlElementControl());
    }

    private List<XmlElementControl> testControls = new List<XmlElementControl>(4);

    public IEnumerable<XmlElementControl> TestControls { get { return testControls; } }
}

和XmlElementControlclass的简化XAML

<UserControl x:Class="Uxmal.Views.XmlElementControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    mc:Ignorable="d">

    <StackPanel Width="500"  Height="80" Orientation="Horizontal" Background="Gray"/>
</UserControl>

但结果是:

enter image description here

窗口的右侧窗格应包含与左窗格相同的列表,但它是空的。

发生了什么事?

1 个答案:

答案 0 :(得分:1)

您的方法有误,list不应包含UI元素,而应包含需要绑定到ListBox的数据。

问题是任何 UI组件只能在单个Visual树中添加,您不能同时将它添加到两个不同的Visual树中。在这种情况下,您尝试添加 XmlElementControl 两个不同的ListBox,绝对无效。

假设创建此测试集合,该集合仅返回数字范围。

public IEnumerable<int> TestCollection
{
   get
   {
      return Enumerable.Range(1, 4);
   }
}

并在XAML中创建ItemTemplate来表示该数据:

<ListBox ItemsSource="{Binding TestCollection,
                            RelativeSource= {RelativeSource FindAncestor,
                                    AncestorType={x:Type local:MainWindow}}}">
  <ListBox.ItemTemplate>
     <DataTemplate>
        <local:XmlElementControl/>
     </DataTemplate>
  </ListBox.ItemTemplate>
</ListBox>

在窗口根级别声明local命名空间,指向XmlElementControl命名空间。