WPF扩展工具包PropertyGrid:选择属性

时间:2016-09-01 05:27:38

标签: c# wpf propertygrid

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

我试过这个,但是不行:

1 个答案:

答案 0 :(得分:1)

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

我建议的解决方案更像是一种解决方法,但如果在代码隐藏中设置了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