【问题标题】:How to dynamically add UserControl to ItemsControl?如何将 UserControl 动态添加到 ItemsControl?
【发布时间】:2014-06-03 22:21:10
【问题描述】:

我有一个在运行时动态创建的 WPF UserControl。根据用户交互,这些控件中的 1-5 个已创建并应添加到 UI。

我在 xaml.cs 代码隐藏中有一个 ObservableCollection<PlayerSpec> PlayerSpecViews。

最初我尝试使用Grid 并动态添加RowDefinitions,但这不起作用。控件将按比例缩小。

然后我尝试使用 ItemsControl,但绑定没有添加 Control,而是添加类型名称。

如何使用数据绑定来垂直添加和放置控件?如果需要,奖励信息可能包括垂直滚动条。

我目前的XAML和绑定如下:

<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>

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>

【问题讨论】:

  • 除非我误解了你,否则你想在已经显示的内容中添加新项目。只需确保您绑定到的集合(PlayerSpecViews)是一个绑定友好的列表(即 ObservableCollection),然后只需在后面的代码中添加到列表中,ItemsControl 就会相应地更新 UI。
  • 我正在使用 ObservableCollection 进行绑定。控件未添加和/或呈现。
  • 您不会对 UI 元素进行ObservableCollection。相反,对包含您要在屏幕上显示的 数据 的相关 数据 项执行 ObservableCollection。发布您的完整代码(包括PlayerSpec 类)
  • 那么使用这里显示的 ItemsControl 的问题是显示类型名称?如果是这种情况,您只需要编辑 DataTemplate 以显示您想要的特定 PlayerSpec 字段,即将 TextBlock 绑定到 PlayerSpec.FirstName,将另一个绑定到 PlayerSpec.LastName 等。
  • 另外,从 ItemTemplate 中删除 StackPanel。它不像我猜你认为的那样做。 ItemTemplate 定义了如何显示each item。如果您需要在 ItemsControl 中定义如何layout 项目,请使用ItemsControl.ItemsPanel 属性。

标签: c# wpf itemscontrol itemsource


【解决方案1】:

你的代码有问题

  • ItemsControl 没有滚动条,所以需要添加一个 ScrollViewer
  • ItemsControl 的 ItemsSource 的绑定源设置为 PlayerSpecViews 看起来不正常,我希望它来自 datacontext
  • 堆栈面板在数据模板中没有任何用途

所以你修改后的代码是

<ScrollViewer>
    <ItemsControl Name="PlayerSpecItems" 
                  HorizontalContentAlignment="Stretch" 
                  ItemsSource="{Binding PlayerSpecViews}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <local:PlayerSpec Margin="1"/>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</ScrollViewer>

因此,这段代码应该为您的 PlayerSpecViews 集合中的每个项目呈现local:PlayerSpec 并进行正确绑定

【讨论】:

  • 只是为了添加到这个答案中,PlayerSpecViews 应该是您的数据上下文中的 ObservableCollection,并且此集合中的每个条目都应该用作您的 ItemControl 中呈现的每个 PlayerSpec 的数据上下文
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-01-01
  • 2015-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-02
相关资源
最近更新 更多