Dynamically adding buttons to ItemsControl
I have a issue that i want your inouts on. I have a outer grid and it has two columns. On first column i am using a ItemsControl that is bind to a a view model (This view model is for dynamically creating buttons). I have a wrap pannel templete define for the Item templete. The 2nd column is for a list box.
I create the objects开发者_如何学运维 for the buttons in the view model and that gets binded to the view.The requiremnet is that if the window hieight fits then all buttons should appear in a single colum (one below the other) else it should come in two columns.
If one column
1
2 3 4If Two Columns :
1 2
3 4The code i have is given below :
ItemsControl:
<Grid>...
<ItemsControl ItemsSource="{Binding buttonsViewModelColl}"
ItemsPanel="{StaticResource WrapPanelTemplateA}"
ItemTemplate="{StaticResource ButtonsDataTempleteA}" Width="{Binding ActualWidth, ElementName=<OuterGrid>}" Grid.Row="2" HorizontalAlignment="Center"/>
</Grid>
WrapPannelTemplete:
<ItemsPanelTemplate x:Key="WrapPanelTemplate">
<WrapPanel/>
</ItemsPanelTemplate>
DataTempleteForButton :
<DataTemplate x:Key="ButtonsDataTempleteA">
<Button
Content="{Binding Path=Text}"
IsEnabled="{Binding Path=IsEnabled}"
Style="{StaticResource StyleButtonA}"
FontFamily="Segoe UI Semibold"
HorizontalAlignment="Left" />
</DataTemplate>
The problem is that on rendering only one or two buttons are visible. If i set teh WrapPannel Orientation to vertical all comes but they donot wrap automatically. Only if i drap and extend teh width of window all are visible. Also teh sequence is not correct :
They come as :
A C
B DAny Ideas.
Another question : Is there a way i can increase the width of the inner grid column based on an outer grid height at runtime in XAML ?
I think what you need is a UniformGrid
not WrapPanel
because you want the total number of buttons, the height of the entire container and the number of columns in the panel to be interdependent. Wrap Panel cannot control the third factor (i.e. number of columns in the panel).
UniformGrid
has Rows
and Columns
property which are perfectly bindable. They can be multi bound to the above 3 factors and a multi value converter can decide what number of rows and columns to display based on some custom heuristic algorithm.
I hope this guides you in correct direction.
I suspect it has something to do with the Width the ItemsControl is allowed. Does it work if you set the WrapPanel's Width manually?
As for your last question, setting the column's width based on the Grid's height, you can simply bind to it.
<ColumnDefinition Width="{Binding ElementName=OuterGrid, Path=ActualHeight}" />
If you need to perform a calculation on that value, I usually use a Converter which accepts a parameter of the Grid's height, and translates it into whatever value I want. I actually have a MathConverter
that use for this kind of thing because I'm too lazy to write my own converter for every binding calculation I want, and the code can be found here
It can be used like:
Width="{Binding ElementName=OuterGrid, Path=ActualHeight,
Converter={StaticResource MathConverter},
ConverterParameter=@VALUE/2}"
Actually, you can probably use the MathConver
to set the Width
of your WrapPanel
, and it should work correctly.
精彩评论