将控件的形状设置为Geometry

时间:2011-10-25 08:17:11

标签: c# wpf xaml

有没有办法获得控件的形状并将其转换为Geometry对象?

我遇到以下情况:在WPF应用程序中,将显示一个弹出窗口。这个弹出窗口没有窗口,它是一个控件,可以看到。应用程序的其余部分将变暗,因为灰色层位于应用程序之上。

现在的问题是,这个灰色层也位于弹出窗口本身之上,这是由应用程序的设计加上点击并打开的元素引起的,弹出窗口也不应被图层隐藏。我决定将剪贴几何图形附加到灰色图层,这很好,但我必须检测所有我不想隐藏的形式和路径。

回到我的问题:有没有办法获得控件的形状并将其转换为Geometry对象?例如。我找到了获取控件的VisualBrush的方法,但也无法转换它 - 或者只是看不出它是如何可能的。

1 个答案:

答案 0 :(得分:2)

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

以下示例使用Panel作为按钮的容器。

Xaml(窗口):

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

背后的代码:     私有FrameworkElementAdorner _adorner;     私人小组_originalParent;

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;
}

这里只显示一个框架元素的简单装饰: class FrameworkElementAdorner:Adorner   {     私有FrameworkElement _child;

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。这有可能吗?