0

DataGrid の要素にアクセスしたいです。次のコードを使用しています。しかし、DataGrid の行を取得できません。null 値を取得しています。null 値を取得している理由と、この問題を解決する方法を知りたいだけです.

 int itemscount = (dgMtHdr.Items.Count);
                dgMtHdr.UpdateLayout();
                for (int rowidx = 0; rowidx < itemscount; rowidx++)
                {

                    Microsoft.Windows.Controls.DataGridRow dgrow = (Microsoft.Windows.Controls.DataGridRow)this.dgMtHdr.ItemContainerGenerator.ContainerFromIndex(rowidx);

                    if (dgrow != null)
                    {
                        DataRow dr = ((DataRowView)dgrow.Item).Row;
                        if (dr != null)
                        {

                                obj = new WPFDataGrid();
                                Microsoft.Windows.Controls.DataGridCell cells = obj.GetCell(dgMtHdr, rowidx, 7);
                                if (cells != null)
                                {
                                    ContentPresenter panel = cells.Content as ContentPresenter;
                                    if (panel != null)
                                    {
                                        ComboBox cmb = obj.GetVisualChild<ComboBox>(panel);
                }
                }
            }
        }
       }
4

1 に答える 1

1

DataGridは内部的にアイテムをホストします。DataGridRowsPresenterその派生元はVirtualizingStackPanel、UI でレンダリングされるアイテムがデフォルトで仮想化をサポートすることを意味します。つまりItemContainer、まだ UI でレンダリングされていないアイテムに対しては生成されません。

そのためnull、UI にレンダリングされていない行をフェッチしようとすると、エラーが発生します。

したがって、仮想化とトレードオフする準備ができている場合は、次のturn off the Virtualizationようにすることができます -

<DataGrid x:Name="dgMtHdr" VirtualizingStackPanel.IsVirtualizing="False"/>

これで、DataGridRowどのインデックス値に対しても null になりません。

また

コンテナが生成されるように、インデックスを手動で呼び出して行を取得できUpdateLayout()ます。ScrollIntoView()詳細については、こちらのリンクを参照してください。リンクから -

if (row == null)
{
    // May be virtualized, bring into view and try again.
    grid.UpdateLayout();
    grid.ScrollIntoView(grid.Items[index]);
    row = (DataGridRow)grid.ItemContainerGenerator.ContainerFromIndex(index);
}

編集

DataGridまだレンダリングされていない2番目のタブにあるためです。そのItemContainerGeneratorため、アイテムに必要な対応するコンテナが生成されていません。したがって、イベントへのフックによってアイテムコンテナが生成されたら、それを行う必要がありますStausChanged-

   dgMtHdr.ItemContainerGenerator.StatusChanged += new 
      EventHandler(ItemContainerGenerator_StatusChanged);

    void ItemContainerGenerator_StatusChanged(object sender, EventArgs e)
    {
        if ((sender as ItemContainerGenerator).Status == 
               GeneratorStatus.ContainersGenerated)
        {
            // ---- Do your work here and you will get rows as you intended ----

            // Make sure to unhook event here, otherwise it will be called 
            // unnecessarily on every status changed and moreover its good
            // practise to unhook events if not in use to avoid any memory
            // leak issue in future.

            dgMtHdr.ItemContainerGenerator.StatusChanged -= 
                                ItemContainerGenerator_StatusChanged;
        }
    }
于 2013-04-14T17:11:08.437 に答える