问题
I have a WPF UserControl which is dynamically created at runtime. Depending on user interaction, from 1-5 of these controls is created and should be added to the UI.
I have an ObservableCollection<PlayerSpec> PlayerSpecViews
in the xaml.cs code-behind.
Initially I tried using a Grid
and dynamically adding RowDefinitions
but that wasn't working. The control would be scaled down in size.
Then I tried using an ItemsControl but the binding was not adding the Control but instead the type name.
How can I use databinding to have the control added and placed in a vertical manner? Bonus info might include vertical scroll bar if needed.
My current XAML and binding are as follows:
<ItemsControl Name="PlayerSpecItems"
HorizontalContentAlignment="Stretch"
ItemsSource="{Binding Source=PlayerSpecViews}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Height="95"
Width="175"
Margin="1">
<local:PlayerSpec/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Classes XAML:
<!-- PlayerSpec -->
<Border Style="{StaticResource InnerBorder}"
HorizontalAlignment="Stretch">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="98"/>
<ColumnDefinition Width="21"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="25"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Label Style="{StaticResource DefaultFont}"
Grid.Column="0"
Grid.Row="0"
VerticalAlignment="Stretch"
VerticalContentAlignment="Center"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Right"
Margin="1"
Content="Name"/>
<TextBox Style="{StaticResource DefaultFont}"
Name="PlayerName"
Background="Transparent"
Grid.Column="1"
Grid.Row="0"
Margin="1"/>
<Grid Grid.Column="0"
Grid.ColumnSpan="2"
Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="25"/>
<ColumnDefinition Width="25"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
</Grid.RowDefinitions>
<Label Style="{StaticResource DefaultFont}"
Grid.Column="2"
Grid.Row="0"
VerticalAlignment="Stretch"
VerticalContentAlignment="Center"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
Content="Automaton"/>
<RadioButton GroupName="PlayerTypeGroup"
Name="PlayerAutomaton"
Grid.Column="1"
Grid.ColumnSpan="2"
Grid.Row="0"
Grid.IsSharedSizeScope="True"
VerticalAlignment="Center">
</RadioButton>
<Label Style="{StaticResource DefaultFont}"
Grid.Column="2"
Grid.Row="1"
VerticalAlignment="Center"
VerticalContentAlignment="Center"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
Content="Human"/>
<RadioButton GroupName="PlayerType"
Name="PlayerHuman"
Grid.Column="1"
Grid.ColumnSpan="2"
Grid.Row="1"
Grid.IsSharedSizeScope="True"
VerticalAlignment="Center">
</RadioButton>
</Grid>
</Grid>
</Border>
回答1:
Issues with your code
- ItemsControl does not have its scrollbar so need to add an ScrollViewer
- Binding source of ItemsControl's ItemsSource is set to PlayerSpecViews which does not look normal, I expect it to be from datacontext
- Stack panel is not serving any purpose in data template
so your revised code is
<ScrollViewer>
<ItemsControl Name="PlayerSpecItems"
HorizontalContentAlignment="Stretch"
ItemsSource="{Binding PlayerSpecViews}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<local:PlayerSpec Margin="1"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
So this code should be rendering local:PlayerSpec
for every item you have in your PlayerSpecViews collection subjected to correct binding
来源:https://stackoverflow.com/questions/24025958/how-to-dynamically-add-usercontrol-to-itemscontrol