Based on the answer to SO question "WPF: arranging collection items in a grid", I have the following:
<ItemsControl Name="itemsControl1" ItemsSource="{Binding MyItems}"> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <Grid Name="theGrid" ShowGridLines="True" /> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> <ItemsControl.ItemContainerStyle> <Style TargetType="{x:Type FrameworkElement}"> <Setter Property="Grid.Row" Value="{Binding RowIndex}" /> <Setter Property="Grid.Column" Value="{Binding ColumnIndex}" /> </Style> </ItemsControl.ItemContainerStyle> </ItemsControl>
Now, I want to set the number of rows and columns of theGrid in the code behind:
theGrid.RowDefinitions.Clear();
theGrid.ColumnDefinitions.Clear();
for (uint i = 0; i < theNumberOfRows; i++)
theGrid.RowDefinitions.Add(new RowDefinition());
for (uint i = 0; i < theNumberOfCols; i++)
theGrid.ColumnDefinitions.Add(new ColumnDefinition());
For this, of course, I need to find the grid. I've used CrimsonX's FindChild in SO question WPF ways to find controls to first locate itemsControl1 and then, using it as the parent, locate theGrid.
Grid FindTheGrid()
{
ItemsControl ic = (ItemsControl)this.FindName("itemsControl1");
Grid theGrid = FindChild<Grid>(ic, "theGrid");
}
This works when called from a button's click event handler. It fails, however, when called from MainWindow's constructor because ic's childrenCount is 0.
int childrenCount = VisualTreeHelper.GetChildrenCount(theParent);
So, how can I set theGrid's row and column collections before the window is shown to the user?
I got tired of writing out
RowDefinitions
andColumnDefinitions
for my Grids, so created some custom DependencyProperties that let you specify the number of Rows/Columns in the Grid definition.The code for the Dependency Properties can be found here and are used like this:
If it gives you an error about the binding then change the
typeof(Grid)
in the DependencyProperty definition totypeof(GridHelpers)
. My first version of the helper class didn't allow bindings and I can't remember which one I have posted.Edit
Here's the code I am using which works, including correctly updating the UI when
SomeInt
changes. I was testing with switchingSomeInt
between 2 and 3 when clicking a buttonXAML
DependencyProperty
Result
WPF generates the "containers" for an ItemsControl's items (usually a DataTemplate) in the background, and they won't be available immediately.
The only way to know when the items are available to use is by subscribing to the StatusChanged event on the ItemsControl's ItemContainerGenerator property:
... and then unsubscribing from within the event handler since you only need it to fire the once:
It's a roundabout way of doing things, for sure, but it's the only way to know that the ItemsControl's items exist in the visual tree.