0

编辑:想通了,问题不是创建名称范围和注册名称。现在工作,将在下面提供答案。

原始问题:

我认为在以编程方式将控件添加到我的 WPF 屏幕时我做错了。

一直在研究这个拖放式可配置 UI 的原型,它允许您使用 WPF DevEx LayoutControl 保存和加载布局。

它工作正常,但是当我从使用在 Visual Studio 中制作的静态 WPF 屏幕转到以编程方式添加了 FrameworkElements 的屏幕时,我打破了它。

下面是向 LayoutControl 添加元素的简单测试:

    public static void InstallItemsInLayoutControl(LayoutControl layoutControl)
    {
        // FAKE TEST VERSION
        Button btn = new Button();
        btn.Name = "TESTBUTTON";
        btn.Content = "Test Me";
        btn.Height = 23;
        btn.Width = 100;
        btn.HorizontalAlignment = HorizontalAlignment.Left;
        btn.VerticalAlignment = VerticalAlignment.Top;
        btn.Width = 100;

        layoutControl.Children.Add(btn);
    }

对于下面的结果,这是添加到否则为空屏幕的唯一项目。

当我加载此屏幕并启用拖放编辑模式时,确实存在该按钮。它不可见,但我可以将它从可用项目中拉到屏幕中,四处移动,然后将布局保存为看起来不错的 XML。例如,这是一个简单的布局,屏幕上除了这个按钮之外什么都没有,在顶层:

  <?xml version="1.0" encoding="utf-8" ?> 
- <LayoutControl Orientation="Vertical">
  <Element ID="TESTBUTTON" HorizontalAlignment="Left" VerticalAlignment="Top" Width="100" Height="23" /> 
  <AvailableItems /> 
  </LayoutControl

如果我从屏幕上删除 Button 并保存,则 XML 看起来会有所不同:

  <?xml version="1.0" encoding="utf-8" ?> 
- <LayoutControl Orientation="Vertical">
- <AvailableItems>
  <Element ID="TESTBUTTON" HorizontalAlignment="Left" VerticalAlignment="Top" Width="100" Height="23" /> 
  </AvailableItems>
  </LayoutControl>

(注意按钮不再在布局中,而是在可用项目中)

我查看了 DevEx 代码,并从 XML 元素中获取 ID,并将其传递给 FrameworkElement.FindName(string),文档中说查看 Name 属性。

我的运行时对象的 ID 和 Name 属性之间似乎存在匹配。

查看 WPF Tree Visualizer,我在可视化树中看到,当我第一次显示此屏幕时,层次结构如下所示:

AdornerDecorator->AvalonAdapter->LayoutControl->ItemsContainer->TESTBUTTON

我不确定 ItemsContainer 的这种间接性是什么,但我怀疑它是“可用项目”容器,它是不在屏幕上但可以在其上定制的东西挂出的地方。

可视化工具显示运行时的 Name 属性确实是 TESTBUTTON。

这个确切的场景是使用未以编程方式添加的项目,我想我的下一步是将一些设计时元素也放在那里。

但我对 WPF 很陌生,有什么明显的我做错了我如何添加我的按钮可能会解释这一点?

谢谢。

4

1 回答 1

1

名称查找确实失败了,因为我没有包含名称范围然后注册名称。

正确的实施是:

  1. 在实例化时为我的 LayoutControl 创建一个名称范围:

    NameScope.SetNameScope(layoutControl, new NameScope());
    
  2. 注册我的按钮名称:

    public static void InstallItemsInLayoutControl(LayoutControl layoutControl)
    {
        // FAKE TEST VERSION
        Button btn = new Button();
        btn.Name = "TESTBUTTON";
        btn.Content = "Test Me";
        btn.Height = 23;
        btn.Width = 100;
        btn.HorizontalAlignment = HorizontalAlignment.Left;
        btn.VerticalAlignment = VerticalAlignment.Top;
        btn.Width = 100;
        layoutControl.RegisterName(btn.Name, btn);  // THIS LINE WAS MISSING
        layoutControl.Children.Add(btn);
    }
    
于 2012-08-02T02:48:44.683 回答