Search code examples
c#wpfstylesobservablecollectionitemscontrol

WPF Style for Interpreting ObservableCollection as Elements of StackPanel


I have an array (stored as an ObservableCollection) of data that I am dynamically instantiating, and I am linking it to an ItemsControl within a StackPanel. The data is formatted like so:

public class VariableValueList<T>
{
    public String Name {get; private set;}
    public IList<T> Values {get; private set;}
    ...
}

and my ObservableCollection<VariableValueList<double>> IVCollection, after constructed, is linked to ItemsControl with the following:

MainWindow.xaml.cs

private void Open_OnClick(object sender, RoutedEventArgs e)
{
    ...
    IndependentVariables.ItemsSource = IVCollection;
}

where IndependentVariables originates here:

MainWindow.xaml

        <StackPanel>
            <ItemsControl Name="IndependentVariables" Style="{StaticResource IVCell}"></ItemsControl>
        </StackPanel>

I need to construct Style IVCell to have access to each VariableValueList<double> (once I get that, it will be trivial to obtain its Name and Values members).

I need the data to be formatted so that, for each element, Name and Values are printed, like so:

Name

Value Value Value ...

Name

Value Value Value ...

...

taking advantage of the existing StackPanel. I understand that there are at least two underlying questions in this problem.

  1. How do I give a Style access to this array? (or: How do I modify a Style after I have the array?)

  2. How do I instantiate new elements within a Style on the fly (e.g. for each array element)?

I really appreciate your help. If I'm trying to structure anything in this way completely wrong, please correct me. I am fairly new to WPF.


Solution

  • You don't need that extra StackPanel, because ItemsControl will create it's own panel for items. Style doesn't need access to array, ItemsControl creates and manages containers for all items automatically. All you need is to provide DataTemplate for both types of items. You can use another ItemsControl inside DataTemplate for VariableValueList<double> to display items contained in Values property. To get horizontal layout, set custom ItemsPanelTemplate for that ItemsControl.

    Simple style to start with:

    <Style TargetType="{x:Type ItemsControl}"
           x:Key="IVCell">
        <Setter Property="ItemTemplate">
            <Setter.Value>
                <DataTemplate>
                    <StackPanel>
                        <TextBlock Text="{Binding Name}" />
                        <ItemsControl ItemsSource="{Binding Values}">
                            <ItemsControl.ItemsPanel>
                                <ItemsPanelTemplate>
                                    <WrapPanel />
                                    <!-- or <StackPanel Orientation="Horizontal"> -->
                                </ItemsPanelTemplate>
                            </ItemsControl.ItemsPanel>
                            <ItemsControl.ItemTemplate>
                                <DataTemplate>
                                    <TextBlock Text="{Binding}" Margin="2,0" />
                                </DataTemplate>
                            </ItemsControl.ItemTemplate>
                        </ItemsControl>
                    </StackPanel>
                </DataTemplate>
            </Setter.Value>
        </Setter>
    </Style>