4

I'm not understanding something about binding. I have a DataTemplate for type Object which is working, but in there I want to make another ListBox and set the data to that of one of the properties of an Object. I've been using Snoop to look at the data context and the data context of the ListBox in the Object DataTemplate is an Object, but there is an error with the ItemsSource and I don't know why. I'm doing ItemsSource={Binding componentList, Mode=TwoWay} and an Object has a componentList and componentList is an ObservableList. What am I missing?

Here's my XAML code:

<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>

And my C# code:

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

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

I make a ListBox in code and set it's ItemsSource to a list of Objects and that's seeing my Object DataTemplate, but that's where it stops

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

any help would be much appreciated. Thanks!

archer
  • 262
  • 2
  • 15
user2013535
  • 73
  • 1
  • 1
  • 7
  • 2
    you have to user CLR properties in your bindings , what you have are fields , componentList with a Setter and Getter. – eran otzap Mar 16 '14 at 22:50
  • wow, I knew it'd be something so easy. Thanks! that made everything fall perfectly into place. Do you actually need DependancyProperties? or just a get; and set;? – user2013535 Mar 16 '14 at 22:55
  • DependancyProperties are the usually the Target Content is the DP where as any this you bind to it from you DataContext is a CLR property. only DP's can be binding Targets , though they can also be a Binding source. regular CLR properties can only by a binding source. – eran otzap Mar 16 '14 at 23:00

1 Answers1

6

In addition to my comments above:

You don't have to create a ListBox in code, create it in XAML and bind a collection to your ItemsSource (Dependency Property).

Like so:

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>

In addition here is a continuation of your code:

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>
archer
  • 262
  • 2
  • 15
eran otzap
  • 12,293
  • 20
  • 84
  • 139