C# 强制执行应用程序模板

C# 强制执行应用程序模板,c#,wpf,c#-4.0,C#,Wpf,C# 4.0,我正在尝试向网格内的WrapPanel动态添加按钮,但WrapPanel引用(\u innerPanel属性)在调用OnApplyTemplate之前无效 以下是XMAL: <s:MyGrid> <WrapPanel x:Name="PART_InnerPanel"> </WrapPanel> </s:MyGrid> 在代码内部: MyGrid g = new MyGrid(); g.ApplyTemplate(); // &l

我正在尝试向网格内的WrapPanel动态添加按钮,但WrapPanel引用(\u innerPanel属性)在调用OnApplyTemplate之前无效

以下是XMAL:

<s:MyGrid>
    <WrapPanel x:Name="PART_InnerPanel">

    </WrapPanel>
</s:MyGrid>
在代码内部:

MyGrid g = new MyGrid();
g.ApplyTemplate(); // <-- doesn't do anything
g.UpdateLayout(); // <-- doesn't do anything
if(g.Panel != null) // <-- it's NULL here as OnApplyTemplate hasn't get called
{
   g.Panel.Children.Add(new Button());
}

或者任何解决方法或更好的方法来实现这一点?

我使用的解决方案是在OnApplyTemplate覆盖中设置_innerPanel(就像您所做的那样),并在我想要使用它时始终检查它是否为null

我从不向外公开该字段,因为不能保证模板设计器会添加该控件。如果您像这样执行检查,则有一个保证,但您仍然依赖于WPF引擎来加载模板

只有在构造控件之后,才能将控件添加到树中并找到模板


所以我认为你不能得到你想要的。

你必须从ItemsControl派生你的控件,以便将子控件添加到你的控件中。公开面板而不是在ItemsControl的items属性中添加项不是一种好的做法,ItemsControl提供了许多自定义外观的方法

我这样做只是为了用最简单的方式展示我在努力做什么。这里不需要包装,它可以是网格、画布、列表、树或任何其他容器。
MyGrid g = new MyGrid();
g.ApplyTemplate(); // <-- doesn't do anything
g.UpdateLayout(); // <-- doesn't do anything
if(g.Panel != null) // <-- it's NULL here as OnApplyTemplate hasn't get called
{
   g.Panel.Children.Add(new Button());
}
MyGrid g = new MyGrid();