在MainWindow的构造方法中,ItemsControl没有子级 [英] ItemsControl has no children during MainWindow's constructor

查看:113
本文介绍了在MainWindow的构造方法中,ItemsControl没有子级的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

基于对SO问题" WPF的回答:网格",我有以下内容:

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>

现在,我想在后面的代码中设置theGrid的行数和列数:

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());

为此,我当然需要找到网格.我在问题中使用了CrimsonX的FindChild问题使用WPF查找控件的方法,首先找到itemsControl1然后,将其用作父级,找到TheGrid.

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");

    }

当从按钮的单击事件处理程序中调用时,此方法有效.但是,由于ic的childrenCount为0,因此从MainWindow的构造函数调用该方法时,它会失败.

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?

推荐答案

WPF在后台为ItemsControl的项目(通常是DataTemplate)生成容器",它们将不会立即可用.

WPF generates the "containers" for an ItemsControl's items (usually a DataTemplate) in the background, and they won't be available immediately.

了解项目何时可用的唯一方法是订阅ItemsControl的ItemContainerGenerator属性上的StatusChanged事件:

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:

itemsControl1.ItemContainerGenerator.StatusChanged += ic_GeneratorStatusChanged;

...,然后取消订阅事件处理程序,因为您只需要触发一次即可:

... and then unsubscribing from within the event handler since you only need it to fire the once:

void ic_GeneratorStatusChanged(object sender, EventArgs e)
{

    if (itemsControl1.ItemContainerGenerator.Status != GeneratorStatus.ContainersGenerated)
        return;

    itemsControl1.ItemContainerGenerator.StatusChanged -= ic_GeneratorStatusChanged;

    // your items are now generated
}

当然,这是一种绕行的处理方式,但这是知道ItemsControl的项目存在于可视树中的唯一方法.

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.

这篇关于在MainWindow的构造方法中,ItemsControl没有子级的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆