强制OnApplyTemplate执行

时间:2011-05-13 16:07:25

标签: c# wpf c#-4.0

我试图动态地将一个按钮添加到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();

或者任何解决方法或更好的方法来执行此操作?

2 个答案:

答案 0 :(得分:0)

我使用的解决方案是在OnApplyTemplate覆盖中设置_innerPanel(就像你一样),并在我想要使用它时始终将其检查为null。

我从不向外暴露这个字段,因为无法保证模板设计师会添加控件。如果您像我一样进行检查有保证,但仍然依赖WPF引擎来加载模板。

只有在构建控件之后,才能将控件添加到树中,并且可以找到模板。

所以我认为你不能满足你的要求。

答案 1 :(得分:0)

您必须从ItemsControl派生控件才能将子控件添加到控件中。曝光Panel而不是在ItemsControl的items属性中添加项目并不是一个好习惯,而ItemsControl为您提供了许多自定义外观的方法。