获取控件的形状为Geometry

本文关键字:Geometry 控件 获取 | 更新日期: 2023-09-27 18:12:32

是否有一种方法可以获得控件的形状并将其转换为几何对象?

我有以下情况:在一个WPF应用程序将显示一个弹出窗口。这个弹出窗口不是窗口,它是一个控件,会显示出来。应用程序的其余部分将变得更暗,因为应用程序上方有一个灰色层。

现在的问题是,这个灰色图层也在弹出框本身的上方,这是由应用程序的设计造成的,加上被点击并打开弹出框的元素也不应该被图层隐藏。我决定在灰色图层上附加一个剪切几何体,这很好,但我必须检测所有我不想隐藏的形状和路径。

那么回到我的问题:是否有一种方法可以获得控件的形状并将其转换为几何对象?例如,我找到了获得控件的VisualBrush的方法,但也不能转换它-或者只是不知道它是如何可能的。

获取控件的形状为Geometry

你可以这样做:从可视树中移除按钮并将其放置在装饰器上。当装饰器关闭时,再次将其附加到原始父组件上。我认为这比剪切任何几何图形要灵活得多,并且使其更加灵活(例如,您可以在装饰器上放置复杂的内容,如usercontrols)

下面的例子使用Panel作为按钮的容器。

Xaml (Window):
<Grid Margin="50" x:Name="myGrid" Background="LightBlue">
<Button x:Name="myButton" Width="80" Height="30" Click="myButton_Click">Show popup</Button>

背后的代码:private FrameworkElementAdorner _adorner;

private void myButton_Click(object sender, RoutedEventArgs e)
{
  if (_adorner == null)
  {
    _adorner = new FrameworkElementAdorner(myGrid);
  }
  // remove the button from the parent panel and attach it to the adorner
  // otherwise remove from adorner and attach to original parent again
  if (_adorner.IsVisible)
  {
    AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(myGrid);
    adornerLayer.Remove(_adorner);
    Panel parent = VisualTreeHelper.GetParent(myButton) as Panel;
    if (parent != null)
    {
      parent.Children.Remove(myButton);
    }
    _originalParent.Children.Add(myButton);
  }
  else
  {
    _originalParent = VisualTreeHelper.GetParent(myButton) as Panel;
    if (_originalParent != null)
    {
      _originalParent.Children.Remove(myButton);
    }
    // Create the Adorner with the original button in it
    _adorner.Child = CreateAdornerContent(myButton);
    AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(myGrid);
    adornerLayer.Add(_adorner);
  }
}
/// <summary>
/// Creates some dummy content for the adorner
/// </summary>
private FrameworkElement CreateAdornerContent(Button myButton)
{
  Grid g = new Grid();
  g.Background = new SolidColorBrush(Colors.Yellow);
  TextBlock tb = new TextBlock();
  tb.Text = "I am the Adorner";
  g.Children.Add(tb);
  g.Children.Add(myButton);
  return g;
}

这里是一个简单的装饰器,它只显示一个frameworkElement:类frameelementadorner:装饰{

public FrameworkElementAdorner(UIElement adornedElement)
  : base(adornedElement)
{
}
protected override int VisualChildrenCount
{
  get
  {
    return 1;
  }
}
protected override Visual GetVisualChild(int index)
{
  if (index != 0) throw new ArgumentOutOfRangeException();
  return _child;
}
public FrameworkElement Child
{
  get
  {
    return _child;
  }
  set
  {
    if (_child != null)
    {
      RemoveVisualChild(_child);
    }
    _child = value;
    if (_child != null)
    {
      AddVisualChild(_child);
    }
  }
}
protected override Size ArrangeOverride(Size finalSize)
{
  _child.Arrange(new Rect(new Point(0, 0), finalSize));
  return new Size(_child.ActualWidth, _child.ActualHeight);
}

}

如果你喜欢,我也可以上传完整的sln。这有可能吗?