How to set ItemsPanelTemplate to a dynamically created Grid in code behind

10,279

Solution 1

You need to create an ItemsPanelTemplate and set it's VisualTree to a FrameworkElementFactory (deprecated) which creates the Grid, or use the XamlReader to parse a XAML-string which specifies the template.

This question contains usage examples of both methods (albeit for a different template property).

An easier method to manipulate the panel at runtime is outlined in this question.

Solution 2

You can do as you want by creating MannualCode in code behind as: 1. Create a Method as following which will return a ItemsPanelTemplate

     private ItemsPanelTemplate GetItemsPanelTemplate()
    {
        string xaml = @"<ItemsPanelTemplate   xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition />
                                </Grid.ColumnDefinitions>
                                <Grid.RowDefinitions>
                                    <RowDefinition />
                                </Grid.RowDefinitions>
                            </Grid>
                    </ItemsPanelTemplate>";
        return XamlReader.Parse(xaml) as ItemsPanelTemplate;
    }
  1. Now add this template in your Listbox ItemsPanel as:

       MyListBox.ItemsPanel = GetItemsPanelTemplate();
    

This is working fine for me. Hope this will help.

Keep Coding....:)

Solution 3

In case that you still have some work to do with the elements, you should take the following (extended) code:

First we need a helper in order to get the element:

// --------------------------------------------------------------------
// This function fetches the WrapPanel from oVisual.
private WrapPanel m_FetchWrapPanel (Visual oVisual)
{
  // WrapPanel to be returned
  WrapPanel oWrapPanel = null;
  // number of childs of oVisual
  int iNumberChilds = VisualTreeHelper.GetChildrenCount (oVisual);
  // and running through the childs
  int i = 0;
  while ( ( i < iNumberChilds ) && ( oWrapPanel == null ) )
  { // fetching visual
    Visual oVisualChild = 
      ( VisualTreeHelper.GetChild (oVisual, i) as Visual );
    if ( ( oVisualChild is WrapPanel ) is true )
    { // found
       oWrapPanel = ( oVisualChild as WrapPanel );
    }
    else
    { // checking the childs of oVisualChild 
      oWrapPanel = m_FetchWrapPanel (oVisualChild);
    };
    // checking next child
    i++;
  };
  // returning WrapPanel
  return (oWrapPanel);
}

Now we create the Panel (or something):

// --------------------------------------------------------------------
private void m_SettingTemplate ()
{
  // the online doc recommends to parse the template
  string xaml = 
    @"<ItemsPanelTemplate
          xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
          xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
        <WrapPanel ItemWidth=""150"" MaxWidth=""150""/>
      </ItemsPanelTemplate>";
  // assigning the template
  oMyListView.ItemsPanel = ( System.Windows.Markup.XamlReader.Parse (xaml) as ItemsPanelTemplate );
  // fetching the WrapPanel
  WrapPanel oWrapPanel = m_WrapPanelAusVisualHolen (oMyListView);
  Debug.Assert (oWrapPanel != null);
  if ( oWrapPanel != null )
  { // adjusting the size of the WrapPanel to the ListView
    Binding oBinding = new Binding ("ActualWidth");
    oBinding.Source = oMyListView;
    oWrapPanel.SetBinding (WrapPanel.MaxWidthProperty, oBinding);
  };
}
Share:
10,279
nabulke
Author by

nabulke

Updated on June 22, 2022

Comments

  • nabulke
    nabulke almost 2 years

    I've got this UserControl defined in XAML and would like to set the ItemsPanelTemplate dynamically in my code behind class (not in the XAML like in the example):

    <UserControl>
        <ItemsControl x:Name="Items">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <Grid> <!-- I want to add this Grid definition in code behind -->
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition />
                        </Grid.ColumnDefinitions>
                        <Grid.RowDefinitions>
                            <RowDefinition />
                        </Grid.RowDefinitions>
                    </Grid>
                </ItemsPanelTemplate>
           </ItemsControl.ItemsPanel>
        </ItemsControl>
    </UserControl>
    

    I tried something like

    this.Items.ItemsPanel.Template = new Grid();
    

    but failed miserably. Any help?

    Background: I only know the number of grid columns and rows at runtime.

  • nabulke
    nabulke over 12 years
    Ok, I have to admit I'm a WPF beginner and I totally don't understand your answer (my fault). I was hoping I could create the grid (new Grid) and just set the Template to the dynamically created Grid (like hinted at in my question). Could you perhaps show an example?
  • H.B.
    H.B. over 12 years
    @nabulke: Did you have a look at the linked question?
  • nabulke
    nabulke over 12 years
    Checking the examples right now. Thanks for adding. I hoped there would be an easier way to set the number of grid rows/columns at runtime though.
  • H.B.
    H.B. over 12 years
    Well, if you want to define it from scratch this is the way to do it, if you just want to edit it (you can add a Grid without definitions) this question here might be what you are looking for.
  • nabulke
    nabulke over 12 years
    The solution posted in the link you provided works great: I added a loaded event handler that adds the cols/rows to the grid, which is defined in XAML. Thanks for your help.