WPF中的ListBox ItemsSource绑定问题

4
我对绑定有些不理解。我有一个用于类型为Object的DataTemplate,它可以正常工作,但是在其中我想创建另一个ListBox并将数据设置为Object的属性之一的数据。我一直在使用Snoop查看数据上下文和对象DataTemplate中ListBox的数据上下文是一个Object,但是ItemsSource存在错误,我不知道为什么。我正在进行ItemsSource={Binding componentList, Mode=TwoWay}操作,而Object具有componentList且componentList是ObservableList。我漏掉了什么?
下面是我的XAML代码:
<Window.Resources>

<DataTemplate DataType="{x:Type properties:Component}">
  <StackPanel>
    <TextBlock Text="TEST COMPONENT" />
    <ListBox DataContext="{Binding propertyList}" ItemsSource="{Binding propertyList}" />
  </StackPanel>
</DataTemplate>

<DataTemplate DataType="{x:Type properties:Object}">
  <StackPanel>
    <TextBlock Text="TEST OBJECT" />
    <ListBox ItemsSource="{Binding componentList, Mode=TwoWay}" />
  </StackPanel>
</DataTemplate>

</Window.Resources>

以下是我的C#代码:

public class Component
{
  public string name;
  public ObservableCollection<IProperty> propertyList;
}

public class Object
{
  public UnsignedProperty objectID;
  public ObservableCollection<Component> componentList;
}

我在代码中创建了一个 ListBox,并将它的 ItemsSource 设置为对象列表,这会显示我的对象 DataTemplate,但这就是它的限制所在。

ListBox properties = new ListBox();
ObservableCollection<Properties.Object> t = new ObservableCollection<Properties.Object>();
t.Add(selectedObject); //potentially more objects
properties.ItemsSource = t;
PropertyPane.Content = properties;

任何帮助都将不胜感激。谢谢!

2
你需要在绑定中使用CLR属性,而你所拥有的是带有Setter和Getter的字段componentList。 - eran otzap
哇,我知道它一定很容易。谢谢!这让一切都完美地落到了位。你实际上需要依赖属性吗?还是只需要get;和set;? - user2013535
依赖属性通常是目标内容,而您从DataContext绑定到它的任何内容都是CLR属性。只有DP可以作为绑定目标,但它们也可以是绑定源。常规CLR属性只能作为绑定源。 - eran otzap
1个回答

6

除了我上面的评论:

您不必在代码中创建一个ListBox,可以在XAML中创建它,并将集合绑定到ItemsSource(依赖属性)。

像这样:

C#:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = this;

        Components.Add(new Object());
        Components.Add(new Object());
    }

    private ObservableCollection<Object> components;
    public ObservableCollection<Object> Components
    {
        get
        {
            if (components == null)
                components = new ObservableCollection<Object>();
            return components;
        }
    }
}

XAML :

<Window>   
   <Grid>
      <ListBox  ItemsSource="{Binding Components, Mode=OneWay}" />        
   </Grid>        
</Window>

此外,这是您代码的延续:

C#:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = this;

        ListBox properties = new ListBox();
        ObservableCollection<Object> t = new ObservableCollection<Object>();
        t.Add(new Object()); //potentially more objects
        properties.ItemsSource = t;
        PropertyPane.Content = properties;
    }        
}

public interface IProperty
{
}

public class Component
{
    public string name;

    private ObservableCollection<IProperty> propertyList;
    public ObservableCollection<IProperty> PropertyList
    {
        get
        {
            if (propertyList == null)
                propertyList = new ObservableCollection<IProperty>();
            return propertyList;
        }
    }
}

public class Object
{
    private ObservableCollection<Component> componentList;
    public ObservableCollection<Component> ComponentList 
    {
        get
        {
            if (componentList == null)
                componentList = new ObservableCollection<Component>();
            return componentList;
        }
    }
}

XAML:

      <DataTemplate DataType="{x:Type local:Component}">
          <StackPanel>
              <TextBlock Text="TEST COMPONENT" />
              <ListBox ItemsSource="{Binding PropertyList, Mode=OneWay}" />
          </StackPanel>
      </DataTemplate>

      <DataTemplate DataType="{x:Type local:Object}">
          <StackPanel>
              <TextBlock Text="TEST OBJECT" />
              <ListBox ItemsSource="{Binding ComponentList, Mode=OneWay}" />
          </StackPanel>
      </DataTemplate>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接