C# 以编程方式创建包含UserControl的UserControl时出现问题

C# 以编程方式创建包含UserControl的UserControl时出现问题,c#,wpf,C#,Wpf,我创建一个usercontrol并将其添加到网格中 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 InB

我创建一个usercontrol并将其添加到网格中

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);
} 
这将导致错误(“指定的视觉对象不是此视觉对象的前身”)。我认为这是因为系统尚未“创建”Exputton,因为:

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));
如果我稍后调用此代码(例如,在创建事件之后通过单击按钮)则有效

为什么会发生这种情况?我如何刷新我的突发事件的“创造”,以便我可以将其用于我的目的

为什么会发生这种情况

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

您可以在
加载的
事件处理程序中保存代码,该事件处理程序将在控件准备好交互时触发:

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

感谢mm8和GazTheDestroyer就理解初始化和加载之间的差异提出的建议

在我的例子中,dispatcher()是一个更好的解决方案:

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

这对我来说很有吸引力。

布局在WPF中是一个多阶段的过程。您无法访问构造函数中的可视化树,因为您的控件尚未添加到可视化树中。你需要对你的控制做出反应
void prova ()
        {
            OutButton btn = m_Bblock.AllOutBtn[0];
            Point pt = btn.TransformToAncestor(GridDropAccept).Transform(new Point(0, 0));
        }