【问题标题】:ItemsControl with Grid as template : add control to Grid以 Grid 为模板的 ItemsControl:向 Grid 添加控件
【发布时间】:2013-03-01 13:21:56
【问题描述】:

Windows Phone 7.1 项目 (XAML)。 我有一个以网格为模板的 itemscontrol,绑定到数据元素的集合,一切正常。 但是,我必须向网格中添加一个额外的图像,它不会绑定到集合。某种标题图片。

我有这个代码:

<ItemsControl ...>
    <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <Grid ShowGridLines="True" x:Name="ShipsGrid">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="0.1*"></ColumnDefinition>
                        <ColumnDefinition Width="0.1*"></ColumnDefinition>
                        <ColumnDefinition Width="0.1*"></ColumnDefinition>
                        <ColumnDefinition Width="0.1*"></ColumnDefinition>
                        <ColumnDefinition Width="0.1*"></ColumnDefinition>
                        <ColumnDefinition Width="0.1*"></ColumnDefinition>
                        <ColumnDefinition Width="0.1*"></ColumnDefinition>
                        <ColumnDefinition Width="0.1*"></ColumnDefinition>
                        <ColumnDefinition Width="0.1*"></ColumnDefinition>
                        <ColumnDefinition Width="0.1*"></ColumnDefinition>
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="0.1*"></RowDefinition>
                        <RowDefinition Height="0.1*"></RowDefinition>
                        <RowDefinition Height="0.1*"></RowDefinition>
                        <RowDefinition Height="0.1*"></RowDefinition>
                        <RowDefinition Height="0.1*"></RowDefinition>
                        <RowDefinition Height="0.1*"></RowDefinition>
                        <RowDefinition Height="0.1*"></RowDefinition>
                        <RowDefinition Height="0.1*"></RowDefinition>
                        <RowDefinition Height="0.1*"></RowDefinition>
                        <RowDefinition Height="0.1*"></RowDefinition>
                    </Grid.RowDefinitions>

                    <!--<Image Source="/images/image.png" x:Name="SuperImage"/>-->

                </Grid>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>

        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Image x:Name="ElementImage" Source="{Binding ImageUri, Mode=OneWay}" />
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </controls:ShipItemsGridControl>

如果我取消注释 ItemsPanelTemplate (x:Name SuperImage) 中的图像,我会收到以下错误:无法显式修改用作 ItemsControl 的 ItemsPanel 的 Panel 的 Children 集合。 ItemsControl 为 Panel 生成子元素。

我已经尝试了几件事,但我无法让它发挥作用。当然我可以将它添加到 itemtemplate 中并且只让它在第一个 item 中可见,但这非常非常难看。

【问题讨论】:

    标签: wpf windows-phone-7 windows-phone-8


    【解决方案1】:

    如果将Image 放在ItemsControl 之上,将两者放在允许重叠控件的父面板中,例如GridCanvas,怎么样?

    <Grid>
        <ItemsControl ... />
        <Image Source="/images/image.png"
               VerticalAlignment="Top" HorizontalAlignment="Left" 
               Margin="5,5,0,0" />
    </Grid>
    

    在代码示例中,我只是为顶部和左侧边距设置了 5 的边距,但您可能需要稍微处理一下才能将图像与您的第一个 Grid 单元格对齐。

    此外,如果您需要动态设置图像的高度/宽度以使其与网格单元格大小相同,您可以将图像的 HeightWidth 属性绑定到 ItemsControl 的 ActualHeight/ActualWidth 和使用转换器计算出该大小的 1/10(我有一个 MathConverter on my blog,这会让这很容易)

    我能想到的唯一其他选择是在生成项目后将其添加到代码隐藏中

    void MyItemsControl_Loaded(object sender, EventArgs e)
    {
        MyItemsControl.ItemContainerGenerator.StatusChanged += 
            ItemContainerGenerator_StatusChanged;
    }
    
    void ItemContainerGenerator_StatusChanged(object sender, EventArgs e)
    {
        if (MyItemsControl.ItemContainerGenerator.Status == 
            System.Windows.Controls.Primitives.GeneratorStatus.ContainersGenerated)
        {
            // Remove ItemContainerGenerator event
            MyItemsControl.ItemContainerGenerator.StatusChanged
                -= ItemContainerGenerator_StatusChanged;
    
            // Add Image to ItemsControl here
        }
    }
    

    虽然这不是很理想,但我会尽我所能先将 Image 放在 ItemsControl 的顶部。

    【讨论】:

    • 感谢您的回复。父容器不是一个选项,因为图像必须位于 Grid 中定义的 10 列/行中。如何在代码隐藏中添加它?我应该绑定到哪个事件?不理想,但我确实认为是最后一种选择。
    • @Boland 根据您的父容器类型,您可以堆叠您的对象,使图像位于您的 ItemsControl 之上。 GridCanvas 都允许子对象“堆叠”在彼此之上。默认情况下,最后添加的子对象位于顶部,但您也可以使用 Canvas.ZIndex 来操作位于顶部的对象。如果我真的走另一条路,我只需使用Loaded 事件将一些代码附加到ItemContainerGenerator,一旦完成生成所有项目,它将添加最终项目。
    • 如果我按照你的方式进行操作(因此图像在 ItemsControl 之外),我必须重新声明所有行和列定义,对吗?我有 10 行和 10 列,所以这将是很多额外的 XAML。
    • @Boland 不,您只需要使用边距或Canvas.Left/Canvas.Top 定位图像。我将在我的答案中更新示例代码...
    • 抱歉,我不知道如何将代码附加到 ItemContainerGenerator?我只能在 itemscontrol 中找到检索索引/对象的方法。没有任何事件可以添加一些控制...
    猜你喜欢
    • 2014-10-29
    • 1970-01-01
    • 2017-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多