2011-10-25 7 views
2

コントロールの形状を取得してGeometryオブジェクトに変換する方法はありますか?コントロールの形状をジオメトリとして取得

次のような状況があります。WPFアプリケーションでポップアップが表示されます。このポップアップはウィンドウではなく、コントロールとして表示されます。アプリケーションの残りの部分は、灰色のレイヤーがアプリケーションの上にあるほど暗くなります。

ここで問題になるのは、この灰色のレイヤーは、アプリケーションのデザインと、クリックされて開いた要素に起因するポップアップ自体の上にもあります。ポップアップもレイヤーによって隠されてはいけません。灰色のレイヤーにクリッピングジオメトリを付けることにしましたが、私は自分で隠したくないフォームとパスをすべて検出する必要があります。

私の質問に戻るには:コントロールの形状を取得し、それをGeometryオブジェクトに変換する方法はありますか?例えば。私はコントロールのVisualBrushを得る方法を見つけましたが、それを変換することはできません - あるいは、それがどのように可能であるかは分かりません。

+1

灰色のレイヤーで覆われないようにポップアップから切り抜きを作成しようとしていますか?その場合は、Z-Orderを使用してコンポーネントの表示順序を制御できます。 http://blogs.msdn.com/b/wpfsdk/archive/2006/06/13/controlling-zorder-using-the- zindex-property.aspx – stuartmclark

+1

私はAdorner/AdornerLayerまたはPopupコントロールを使用します。両方の要素は、他のコントロールの上に情報を表示するように設計されており、ビジュアルコンテンツの上にポップアップを表示する必要があります。 を参照してください。http://msdn.microsoft.com/en-us/library/ms749018.aspx および http://msdn.microsoft.com/en-us/library/ms747117.aspx – SvenG

+0

あなたはどちらも間違いありませんポップアップのために、私のニーズに合ったZ-インデックスやコントロールを使う方がはるかに簡単です。私はこの可能性の1つを使用しようとします。しかし、ソース管理はどうですか?クリックされたボタンはポップアップオーバーレイで覆われていないはずです。 – MatthiasG

答えて

2

あなたは次のようにすることができます: ビジュアルツリーからボタンを削除し、それをアドナーに配置します。 adornerが閉じると元の親に再度添付します。 これは、ジオメトリをクリップするよりもはるかに柔軟性があり、柔軟性に優れていると思います(たとえば、ユーザーコントロールのような複雑なコンテンツをアドナーに配置するなど)。

次の例では、ボタンのコンテナとして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。 プライベートPanel _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; 
} 

そしてここだけのFrameworkElementを表示する簡単なadorner: クラス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をアップロードすることができます。これは何とかここに可能ですか?

+0

あなたの答えは、それが確実に働くので、簡単な解決策になります。残念ながら、私たちはフレームワークを使用しており、私たちの顧客からの厳格な仕様では許可していないので、ビジュアルツリーを変更することはできません。私は基本的なコントロールのためのクリッピングメソッドを使用する必要があります。ポップアップ自体は、ZIndexが高いレイヤーに挿入することでクリッピングすることなく表示できますが、より深いレイヤーのコントロールは変更できません。 – MatthiasG

+0

あまりにも悪い:(あなたの理想的な解決策を見つけることができて幸運を... – SvenG

+0

あなたは本当に良い仕事をしたようにこれを答えとしてマークしました。 – MatthiasG

関連する問題