我试图动态地将一个按钮添加到Grid内部的WrapPanel,但是在调用OnApplyTemplate之前,WrapPanel引用( _innerPanel属性)无效。
这是XMAL:
<s:MyGrid>
<WrapPanel x:Name="PART_InnerPanel">
</WrapPanel>
</s:MyGrid>
MyGrid类:
public class MyGrid: Grid
{
WrapPanel _innerPanel;
public WrapPanel Panel
{
get{return _innerPanel;}
}
static MyGrid()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(MyGrid), new FrameworkPropertyMetadata(typeof(MyGrid)));
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
_innerPanel = Template.FindName("PART_InnerPanel", this) as WrapPanel;
if (_innerPanel == null)
throw new ResourceReferenceKeyNotFoundException("Invalid template");
}
}
代码内部:
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());
}
如何获取在行
之后的XAML中定义的WrapPanel的引用MyGrid g = new MyGrid();
或者任何解决方法或更好的方法来执行此操作?
答案 0 :(得分:0)
我使用的解决方案是在OnApplyTemplate覆盖中设置_innerPanel(就像你一样),并在我想要使用它时始终将其检查为null。
我从不向外暴露这个字段,因为无法保证模板设计师会添加控件。如果您像我一样进行检查有保证,但仍然依赖WPF引擎来加载模板。
只有在构建控件之后,才能将控件添加到树中,并且可以找到模板。
所以我认为你不能满足你的要求。
答案 1 :(得分:0)
您必须从ItemsControl派生控件才能将子控件添加到控件中。曝光Panel而不是在ItemsControl的items属性中添加项目并不是一个好习惯,而ItemsControl为您提供了许多自定义外观的方法。