WPF 扩展工具包 PropertyGrid:Select 属性

WPF Extended Toolkit PropertyGrid: Select property

我想将焦点设置在 属性 网格的第一项上。所以在添加一个对象并绑定到PropertyGrid后,可以改变第一个属性.

我试过了,但没用:

propertyGrid.Focus();
propertyGrid.SelectedProperty = propertyGrid.Properties[0];

不幸的是,似乎没有内置的解决方案。

我建议的解决方案更像是一种变通方法,但它应该正确可视化-Select SelectedProperty 如果它已在代码隐藏中设置。

首先,我们需要一些扩展:

 public static class Extensions {
    public static T GetDescendantByType<T>(this Visual element) where T : class {
      if (element == null) {
        return default(T);
      }
      if (element.GetType() == typeof(T)) {
        return element as T;
      }
      T foundElement = null;
      if (element is FrameworkElement) {
        (element as FrameworkElement).ApplyTemplate();
      }
      for (var i = 0; i < VisualTreeHelper.GetChildrenCount(element); i++) {
        var visual = VisualTreeHelper.GetChild(element, i) as Visual;
        foundElement = visual.GetDescendantByType<T>();
        if (foundElement != null) {
          break;
        }
      }
      return foundElement;
    }

    public static void BringItemIntoView(this ItemsControl itemsControl, object item) {
      var generator = itemsControl.ItemContainerGenerator;

      if (!TryBringContainerIntoView(generator, item)) {
        EventHandler handler = null;
        handler = (sender, e) =>
        {
          switch (generator.Status) {
            case GeneratorStatus.ContainersGenerated:
              TryBringContainerIntoView(generator, item);
              break;
            case GeneratorStatus.Error:
              generator.StatusChanged -= handler;
              break;
            case GeneratorStatus.GeneratingContainers:
              return;
            case GeneratorStatus.NotStarted:
              return;
            default:
              break;
          }
        };

        generator.StatusChanged += handler;
      }
    }

    private static bool TryBringContainerIntoView(ItemContainerGenerator generator, object item) {
      var container = generator.ContainerFromItem(item) as FrameworkElement;
      if (container != null) {
        container.BringIntoView();
        return true;
      }
      return false;
    }

  }

在此之后,您可以轻松地执行以下操作:

//Register to the SelectedPropertyItemChanged-Event
this._propertyGrid.SelectedPropertyItemChanged += this.PropertyGridSelectedPropertyItemChanged;
//Set any Property by index
this._propertyGrid.SelectedProperty = this._propertyGrid.Properties[3];

终于完成神奇的高亮显示

private void PropertyGridSelectedPropertyItemChanged(object sender, RoutedPropertyChangedEventArgs<PropertyItemBase> e) {
      var pic = this._propertyGrid.GetDescendantByType<PropertyItemsControl>();
      pic.BringItemIntoView(e.NewValue);
      // UPDATE -> Move Focus to ValueBox
      FocusManager.SetFocusedElement(pic,e.NewValue);
      var xx = Keyboard.FocusedElement as UIElement;
      xx?.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
    }

关闭

这里一切的关键是,了解 PropertyItemsControl 这是一个包含所有属性的 ItemsControl。

希望对您有所帮助!

学分

Bring ItemsControl into view
Get Nested element from a Control