是否有更简单的方法来对未知类型进行类型转换?

时间:2010-05-24 20:13:55

标签: c# wpf xaml wpf-controls

我正在编写一个函数来递归我的XAML并将所有控件添加到哈希表中,其名称是键。不幸的是,似乎我必须通过并列出所有可能的类型:

void Recurse_Controls(object start)
{
    string start_type = start.GetType().ToString();

    if (start_type == "StackPanel")
    {
        ControlsByName.Add(((StackPanel)start).Name, start);
        foreach (object item in ((StackPanel)start).Children)
        {
            Recurse_Controls(item);
        }
    }

    if (start_type == "Grid")
    {
        ControlsByName.Add(((Grid)start).Name, start);
        foreach (object item in ((Grid)start).Children)
        {
            Recurse_Controls(item);
        }
    }
}

有更简单的方法吗?

3 个答案:

答案 0 :(得分:4)

您真正想要做的是获取逻辑树中的所有对象。逻辑树将包含除控件之外的其他内容(例如RowDefinitions),因此在将对象添加到字典之前,应检查以确保该对象实际存在。

由于Name属性是在FrameworkElement(和FrameworkContentElement,但它们使用AddOwner,因此这两个属性实际上是同一个实例)上定义的,因此您可以使用GetValue来检索值。这应该做你需要的:

void Recurse_Controls(DependencyObject start)
{
     if (start == null) return;

     var name = (string)start.GetValue(FrameworkElement.NameProperty);
     if (!String.IsNullOrEmpty(name))
         ControlsByName.Add(name, start);

     foreach (var child in LogicalTreeHelper.GetChildren(start))
         Recurse_Controls(child);
}

旁注:通过使用队列而不是递归,可以轻松地进行迭代:

void Add_Controls(DependencyObject start)
{
     if (start == null) return;
     var items = new Queue<DependencyObject>();
     items.Enqueue(start);

     while (items.Count > 0)
     {
         var item = items.Dequeue();
         var name = (string)item.GetValue(FrameworkElement.NameProperty);
         if (!String.IsNullOrEmpty(name))
             ControlsByName.Add(name, item);

         foreach (var child in LogicalTreeHelper.GetChildren(item))
             items.Enqueue(child);
     }
}

答案 1 :(得分:0)

您可以循环遍历基类型,例如按钮控制等,或者循环嵌套类型的ContainerControl。这将大大削减if条款的数量。

我想知道为什么你会需要这样的东西。您正在尝试使用Wat来列出所有控件吗?

编辑: 刚刚意识到你不能像这样使用基类型;您需要将start.GetType().ToString()替换为start.GetType().BaseType.ToString();

答案 2 :(得分:0)

它不会比你做得好多少。但是,您应该使用is子句而不是比较字符串。这更安全,更快。您也可以在支票中使用基类。例如,对于所有派生类,if (start is ButtonBase)也是如此(如果这适合您的需要)。