views:

509

answers:

3

I'm wondering how one could use template databinding to accomplish what the following code produces (a grid of checkboxes with some associated text):

  int tbIndex = 0;
  for (int i = 1; i < 5; i++) {
   StackPanel pan = new StackPanel();
   pan.Orientation = Orientation.Horizontal;
   pan.Margin = new Thickness(3);
   pan.Name = "RowPanel" + i;
   for (int j = 0; j < 3; j++) {
    CheckBox cb = new CheckBox();
    TextBlock block = new TextBlock();
    block.Width = 75;
    block.Text = "Item " + (++tbIndex).ToString();
    pan.Children.Add( cb );
    pan.Children.Add( block );
   }
   ContentPanel.Children.Add( pan );
  }

In ASP.NET, for example, one could use a DataList and set the repeat direction to horizontal and bind. Is there an equivalent way that is less imperative and more declarative (ie. done up front with a template and using generic "databinding" facilities)?

+1  A: 
<ItemsControl ItemsSource="{Binding YourListOfItems}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <CheckBox IsChecked="{Binding YourIsChecked}"/>
                <TextBlock Text="{Binding YourText}"/>
            </StackPanel>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

This assumes you have a collection of objects in a property called YourListOfItems. In each of those objects, it assumes the existence of properties called YourIsChecked (bool) and YourText (probably string).

HTH, Kent

Kent Boogaart
Does that wrap when it reaches the right border of the container?
AnthonyWJones
I'm not sure how wrapping even factors into this question. If you need things to wrap, use the appropriate container. A StackPanel is not the appropriate container for wrapping.
Kent Boogaart
@Kent - thanks but this is what I started with and AnthonyWJones is right that it doesn't wrap. I think I'll start with the Silverlight toolkit Wrap Panel.
David in Dakota
Like I said - StackPanel won't wrap. Use a Grid instead and use shared size groups.
Kent Boogaart
A: 

The Silverlight toolkit has a Wrap Panel.

Here is a description of it.

Being an open source project you could find out how it does it and create something similar for WPF, I can't beleive that no one appears to have ported this tool kit to full WPF already.

AnthonyWJones
The full WPF implementation already has a WrapPanel. Silverlight did not have it yet so they added it to the Silverlight Toolkit. Same goes for DockPanel.
Bryan Anderson
A: 

AnthonyWJones has it right that the Wrap Panel is a good approach but Kent went through the trouble of demonstrating how once could use the ItemSource (albeit with the StackPanel which doesn't achieve the goal). As such I'll post the code which demonstrates the declarative equivalent:

<ItemsControl x:Name="myItems" Width="300">
    <ItemsControl.ItemsPanel>
     <ItemsPanelTemplate>
      <controls:WrapPanel x:Name="itemsWrapPanel" Margin="0" Orientation="Horizontal" />
     </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
     <DataTemplate>
      <StackPanel Orientation="Horizontal" Width="100">
       <CheckBox IsChecked="{Binding MyCheckedProperty, Mode=TwoWay}" x:Name="IsSelectedCheckBox" Height="25"></CheckBox>
       <TextBlock Height="12" Text="{Binding MyTextProperty}" Margin="0" />
      </StackPanel>
     </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

A small gotcha is that the DataTemplate expects a single child so using a StackPanel with horizontal orientation keeps things flowing.

David in Dakota