以编程方式包含UserControl的UserControl创建问题

时间:2019-11-20 11:28:20

标签: c# wpf

我创建了一个用户控件,并将其添加到网格中。

BuildingBlock m_Bblock = new BuildingBlocks.BuildingBlock(2, 2);

m_grid.Children.Add(m_Bblock);

我的BuildingBlock的构造函数将输入和输出按钮的数量作为输入,它们都是用户控件。 在构造函数内部,我具有:

 for (int kk = 0; kk < NumIn; ++kk)

{
   InButton inbtn = new InButton();

   inbtn.m_Button_Click += Button_In_Click;

   InStackPanel.Children.Add(inbtn);

   AllInBtn.Add(inbtn);
} 

以及类似的OutButton代码。

我需要了解第一个OutButton在网格上的位置信息,所以我使用了:

OutButton btn = m_Bblock.AllOutBtn[0];
Point pt = btn.TransformToAncestor(m_grid).Transform(new Point(0, 0));

这会导致错误(“指定的Visual并非此Visual的前身”)。我认为这是由于系统尚未“创建” OutButton,因为:

Point pt = m_Bblock.TransformToAncestor(GridDropAccept).Transform(new Point(0, 0));

有效并且:

OutButton btn = m_Bblock.AllOutBtn[0];
Point pt = btn.TransformToAncestor(m_grid).Transform(new Point(0, 0));

如果以后再调用此代码(例如,在创建事件之后通过单击按钮)会起作用。

为什么会这样?如何刷新OutButton的“创建”,以便可以将其用于自己的目的?

2 个答案:

答案 0 :(得分:0)

  

为什么会这样?

因为构造函数执行时尚未在屏幕上呈现控件。这发生在稍后的阶段。

您可以将代码放入Loaded事件处理程序中,该事件处理程序将在控件准备好进行交互时触发:

this.Loaded += (s, e) => 
{
    OutButton btn = m_Bblock.AllOutBtn[0];
    Point pt = btn.TransformToAncestor(m_grid).Transform(new Point(0, 0));
};

答案 1 :(得分:0)

感谢mm8和GazTheDestroyer对理解初始化和加载之间的区别的建议。

在我的情况下,调度员(Is there a "All Children loaded" event in WPF)是更好的解决方案:

Dispatcher.BeginInvoke(DispatcherPriority.Input, new Action(() => {
               prova(); })); 

具有:

void prova ()
        {
            OutButton btn = m_Bblock.AllOutBtn[0];
            Point pt = btn.TransformToAncestor(GridDropAccept).Transform(new Point(0, 0));
        }

那对我来说就像一种魅力。

相关问题