views:

181

answers:

3

Hi,

I have an object with two arrays of strings. The object is data bound to a listbox. One list is bound as the list's ItemsSource. The other, which is the thing causing me trouble, needs to be bound to a combobox that's part of a DataTemplate that is set to the list's ItemTemplate. Basically each item on the listbox has the corresponding element of the first list and a combo box that contains the second list. In other words, every item in the list has the same combobox of choices.

The problem comes from the fact that it winds up that the DataTemplate is data bound the first list. I was expecting the DataTemplate to be databound to the object that contains both lists. Now, with that happening, I can't figure out what kind of binding syntax I need to get at the "parent" of the DataContext, if that's even possible.

Can someone point me in the right direction?

Thanks!

+1  A: 

I don't think you want to do what you are trying to do. You are asking for the pain.

What you'd likely want to do instead is reference a static collection inside each item in your collection that contains the subcollection for your ComboBox. So:

//Pseudocode
TopLevelEntity
{
     SubLevelEntity[] SubItemsForComboBox;
}

This way for each "TopLevelEntity" you'd be prepared with your collection of items for the combo box.

<ListView ItemsSource="{StaticResource MyCollectionOfTopLevelEntities}">
    <ItemTemplate>
        <DataTemplate>
            <ComboBox ItemsSource="{Binding SubItemsForComboBox} />
        </DataTemplate>
    </ItemTemplate>
</ListView>

As is my way, I've not verified this code and it's possible it doesn't even compile, but the theory should be sound.

Let us know what you decide to do.

Anderson Imes
From what I can understand from your suggestion, the disadvantage would be that every item would have a duplicate list of options for the combobox.
Steve the Plant
Well technically you could set them all equal to the same instance of your collection, but the point is taken.
Anderson Imes
+1  A: 

If I'm understanding you correctly, you can set the DataContext of your ListBox to an instance of a class (in my example I do it in code by: list.DataContext = myclass;) and you want to set the ItemSource of your listbox to a list in the class (ie Items) and the itemssource of your combobox to another list in the class (ie Values). Here's my xaml that seems to work:

<ListBox Name="list" ItemsSource="{Binding Items}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <TextBlock Text="{Binding}"/>
                <ComboBox ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBox}}, Path=DataContext.Values}"/>
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

and heres the class that I'm binding to:

public class AClass
{

    protected List<string> _Items;
    public List<string> Items
    {
        get
        {
            if (_Items == null)
            {
                _Items = new List<string>();
            }
            return _Items;
        }
    }


    protected List<string> _Values;
    public List<string> Values
    {
        get
        {
            if (_Values == null)
            {
                _Values = new List<string>();
            }
            return _Values;
        }
    }
}

In code I created an instance of AClass, added Items and Values, and set the instance to the DataContext of the listbox.

Mark Synowiec
Perfect! This is exactly what I was trying to achieve. Thanks Mark!
Steve the Plant
When I was trying to find a solution, I realized that using RelativeSource was key, but in my mind I wanted to find a member in the DataContext and not the ui element hierarchy. Your solution solidified the fact that RelativeSource only works for UI elements and not any data they contain. Thanks again!
Steve the Plant
Glad I can help. I had a similar situation in code, with two arrays in a data structure, one used to categorize the other. For serialization, it made the most sense to structure them that way, plus using the datacontext will allow me to load a complete different set if I need to. It's pretty nice the way they set those things up in WPF. :)
Mark Synowiec
A: 

First of all as Anderson suggests I would suggest you to re-design your classes to get Combobox items from some where outside as statically referenced list But here is a workaround for your current scenario. I am assuming that your Main Object of interest('Parent') is the DataContext of the ListBox. which you wanted to reference inside the DataTemplateLevel. Idea is to walk up to the ListBox and get the DataContext

 <Combobox DataContext="{Binding DataContext, RelativeSource={RelativeSource AncestorType={x:Type ListBox}}}" ItemsSource="{Binding YourCollection}" ....
Jobi Joy