【问题标题】:Get object by its Uid in WPF通过 WPF 中的 Uid 获取对象
【发布时间】:2010-12-25 15:33:44
【问题描述】:

我在 WPF 中有一个具有唯一 Uid 的控件。如何通过 Uid 检索对象?

【问题讨论】:

  • 请详细说明。你的UID是什么?它是如何设置的?
  • 它是 wpf 或 silverlight 中任何控件的依赖属性。我已经设法解决了这个问题,但我想知道是否存在内置方法。

标签: wpf object wpf-controls fetch


【解决方案1】:

我对最佳答案的一个问题是它不会在内容控件(例如用户控件)内部查找其内容中的元素。为了在这些内部进行搜索,我扩展了函数以查看兼容控件的 Content 属性。

public static UIElement FindUid(this DependencyObject parent, string uid)
{
    var count = VisualTreeHelper.GetChildrenCount(parent);

    for (int i = 0; i < count; i++)
    {
        var el = VisualTreeHelper.GetChild(parent, i) as UIElement;
        if (el == null) continue;

        if (el.Uid == uid) return el;

        el = el.FindUid(uid);
        if (el != null) return el;
    }

    if (parent is ContentControl)
    {
        UIElement content = (parent as ContentControl).Content as UIElement;
        if (content != null)
        {
            if (content.Uid == uid) return content;

            var el = content.FindUid(uid);
            if (el != null) return el;
        }
    }
    return null;
}

【讨论】:

    【解决方案2】:

    这样更好。

    public static UIElement FindUid(this DependencyObject parent, string uid) {
        int count = VisualTreeHelper.GetChildrenCount(parent);
    
        for (int i = 0; i < count; i++) {
            UIElement el = VisualTreeHelper.GetChild(parent, i) as UIElement;
            if (el != null) {
                if (el.Uid == uid) { return el; }
                el = el.FindUid(uid);
            }
        }
            return null;
    }
    

    【讨论】:

    • 如果您的代码不起作用,那就再好不过了。你的递归被打破了。 el.FindUid(uid)的结果,如果不为null,必须返回。
    【解决方案3】:
    public static UIElement GetByUid(DependencyObject rootElement, string uid)
    {
        foreach (UIElement element in LogicalTreeHelper.GetChildren(rootElement).OfType<UIElement>())
        {
            if (element.Uid == uid)
                return element;
            UIElement resultChildren = GetByUid(element, uid);
            if (resultChildren != null)
                return resultChildren;
        }
        return null;
    }
    

    【讨论】:

      【解决方案4】:

      您几乎必须通过蛮力来做到这一点。这是您可以使用的辅助扩展方法:

      private static UIElement FindUid(this DependencyObject parent, string uid)
      {
          var count = VisualTreeHelper.GetChildrenCount(parent);
          if (count == 0) return null;
      
          for (int i = 0; i < count; i++)
          {
              var el = VisualTreeHelper.GetChild(parent, i) as UIElement;
              if (el == null) continue;
      
              if (el.Uid == uid) return el;
      
              el = el.FindUid(uid);
              if (el != null) return el;
          }
          return null;
      }
      

      那么你可以这样称呼它:

      var el = FindUid("someUid");
      

      【讨论】:

      • GetChild(parent, N) 的复杂度不是 O(N) 吗? foreach 方法对我来说似乎更清晰(更清晰)。
      • msdn 所述,如果未设置AutomationId,WindowsAutomationFramework 将默认为Uid(如果已设置)或ControlName(如果已设置)(选中通过检查.exe)。所以在某些情况下,AutomationIds 的工具就足够了。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-11-14
      • 1970-01-01
      • 1970-01-01
      • 2011-08-09
      • 2014-02-04
      • 2018-04-22
      • 1970-01-01
      相关资源
      最近更新 更多