2011-06-23 18 views
5

私はWPFで以下の画像に似たものを作成しようとしています。このコントロールは、私のアプリのすべての基本ビューとなるように設計されており、背景(おそらくある種のグラデーション)を持つWindowコントロールの中に座っています。次のようにWPFカットコーナー要素

要件は次のとおりです。 "の背景を持っている右上のタブ探しコーナーをカットオフ

  • (左上、左下と右下)3つの両側の角を丸く
  • ウィンドウからの背景のグラデーションが透明になるように透明にします(実際には切り取られたように見えます)
  • タイトル領域はコンテンツコンテナでなければならないので、アイコンやテキストなどの中に何も置くことができません。
  • コンテンツエリア最低限必要

私はこれを数時間戦ってきましたが、WPFには新しくなっています。これは、円で周りを走っている自分を見つけ出す。 WPFの柔軟性には大きなメリットがあると思いますが、始める人にとってはそれほど難しいことです。

ご協力いただければ幸いです。ありがとう!

Content Layout

答えて

4

Tabby

私はクリップを '塗りつぶす'方法を知らないので、クリップでコードを作りました。

コード:

public class Tabby : HeaderedContentControl 
{ 
    static Tabby() 
    { 
     DefaultStyleKeyProperty.OverrideMetadata(typeof(Tabby), new FrameworkPropertyMetadata(typeof(Tabby))); 
    } 

    public double DogEar 
    { 
     get { return (double)GetValue(DogEarProperty); } 
     set { SetValue(DogEarProperty, value); } 
    } 

    public static readonly DependencyProperty DogEarProperty = 
     DependencyProperty.Register("DogEar", 
     typeof(double), 
     typeof(Tabby), 
     new UIPropertyMetadata(8.0, DogEarPropertyChanged)); 

    private static void DogEarPropertyChanged(
     DependencyObject obj, 
     DependencyPropertyChangedEventArgs e) 
    { 
     ((Tabby)obj).InvalidateVisual(); 
    } 

    public Tabby() 
    { 
     this.SizeChanged += new SizeChangedEventHandler(Tabby_SizeChanged); 
    } 

    void Tabby_SizeChanged(object sender, SizeChangedEventArgs e) 
    { 
     var clip = new PathGeometry(); 
     clip.Figures = new PathFigureCollection(); 
     clip.Figures.Add(
      new PathFigure(
       new Point(0, 0), 
       new[] { 
        new LineSegment(new Point(this.ActualWidth - DogEar, 0), true), 
        new LineSegment(new Point(this.ActualWidth, DogEar), true), 
        new LineSegment(new Point(this.ActualWidth, this.ActualHeight), true), 
        new LineSegment(new Point(0, this.ActualHeight), true) }, 
       true) 
     ); 
     this.Clip = clip; 
    } 
} 

Generic.xaml

<Style TargetType="{x:Type local:Tabby}"> 
    <Setter Property="Padding" 
      Value="5" /> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type local:Tabby}"> 
       <Grid> 
        <Grid.RowDefinitions> 
         <RowDefinition Height="auto" /> 
         <RowDefinition Height="auto" /> 
        </Grid.RowDefinitions> 
        <Border CornerRadius="3,0,0,0" 
          BorderBrush="Black" 
          BorderThickness="1" 
          Background="Black"> 
         <ContentPresenter Content="{TemplateBinding Header}" 
              Margin="{TemplateBinding Padding}" /> 
        </Border> 
        <Border CornerRadius="0,0,3,3" 
          BorderBrush="Black" 
          BorderThickness="1" 
          Background="White" 
          Grid.Row="1"> 

         <ContentPresenter Content="{TemplateBinding Content}" 
              Margin="{TemplateBinding Padding}" /> 
        </Border> 
       </Grid> 

      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

それを使用する:

<my:Tabby DogEar="12" 
      x:Name="tabby1"> 
    <my:Tabby.Header> 
     <TextBlock Foreground="White">Header</TextBlock> 
    </my:Tabby.Header> 
    <my:Tabby.Content> 
     <TextBlock Text="Content can be anything" /> 
    </my:Tabby.Content> 
</my:Tabby> 
あなたはより多くの助け色など ここに行くを制御するために複数のプロパティを追加することが必要な場合は、私に教えてください
+0

完璧!これは私が必要としていたものではありません。今私はWPFからいつも浮かび上がっているような1つの質問...あなたがしたことを思い付くことを世界でどうやって学んだのですか?このような便利なファッションでWPFを実際に学習するためのリソースは、信じられないほど不足しているようです。 – RubyHaus

+0

5年前、私はあなたが今いる厳しい部分をしました。私はその本を読んで、複数のプロジェクトをコーディングし、間違いを犯したり、他の人に尋ねました(その周りにはそれほど多くはありませんでしたが、私はWPFで働く人々の一部にアクセスできるほど幸運でした)。そして今でも私はまだ学んでいます。ハングアップすると、あなたはそこに着くでしょう。 –

4

始めるためにこれを試してみてください:

<Grid Width="100" Height="100"> 
    <Border Background="Green" CornerRadius="8,0,8,8"> 
     <Border.Clip> 
     <PathGeometry> 
      <PathGeometry.Figures> 
      <PathFigure StartPoint="0,0"> 
       <PathFigure.Segments> 
       <LineSegment Point="90,0"/> 
       <LineSegment Point="100,10"/> 
       <LineSegment Point="100,100"/> 
       <LineSegment Point="0,100"/> 
       </PathFigure.Segments> 
      </PathFigure> 
      </PathGeometry.Figures> 
     </PathGeometry> 
     </Border.Clip> 
    </Border> 
    </Grid> 
+0

これは完璧だと思います!ありがとう!! – RubyHaus

+0

あなたのメソッドはかなりうまくいきましたが、以下の答え( "Tabby"コントロール)は、簡単に再利用できるものが必要だったので、私にとってはうまくいっていました。私はあなたのために私の上の投票を残しました。再度、感謝します! – RubyHaus

+0

私もこのように始めましたが、すぐに私はコントロールのサイズを知らず、クリップのサイズを推測しなければならなくなってしまいました。 –

0

ここで私はカスタムコントロールを使用して一緒に入れて、いくつかのコードがあります。

コントロールコード:

using System; 
using System.Windows; 
using System.Windows.Controls; 

namespace Test 
{ 
    public class ContentCard : HeaderedContentControl 
    { 
     static ContentCard() 
     { 
      DefaultStyleKeyProperty.OverrideMetadata(typeof(ContentCard), new FrameworkPropertyMetadata(typeof(ContentCard))); 
     } 
    } 
} 

(テーマ/ Generic.xamlフォルダ内の)コントロールのXAML

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:test="clr-namespace:Test"> 
    <Style TargetType="{x:Type test:ContentCard}"> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="{x:Type test:ContentCard}"> 
        <Grid Background="Transparent"> 
         <Grid.RowDefinitions> 
          <RowDefinition Height="30" /> 
          <RowDefinition Height="*" /> 
         </Grid.RowDefinitions> 
         <Grid.ColumnDefinitions> 
          <ColumnDefinition Width="*" /> 
          <ColumnDefinition Width="20" /> 
         </Grid.ColumnDefinitions> 

         <Border Grid.Row="0" Grid.Column="0" Background="{TemplateBinding Background}" CornerRadius="10,0,0,0" Height="30"> 
          <ContentControl Content="{TemplateBinding Header}" VerticalAlignment="Center" Margin="10,0,0,0" /> 
         </Border> 
         <Path Grid.Row="0" Grid.Column="1" Fill="{TemplateBinding Background}" Data="M0,0 L20,15 L20,30 L0,30 L0,0Z"/> 
         <Border Grid.Row="1" Grid.ColumnSpan="2" BorderBrush="{TemplateBinding Background}" BorderThickness="1,0,1,1" CornerRadius="0,0,10,10" Padding="5" Background="White"> 
          <ContentControl Content="{TemplateBinding Content}" /> 
         </Border> 
        </Grid> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 
</ResourceDictionary> 

これは、あなたがそれを使用する方法である:

<test:ContentCard Grid.RowSpan="4" Grid.ColumnSpan="2" Margin="200" Background="Black"> 
    <test:ContentCard.Header> 
     <TextBlock Text="Title" Foreground="White" /> 
    </test:ContentCard.Header> 
    <test:ContentCard.Content> 
     <TextBlock Text="This is some content" Foreground="Black" /> 
    </test:ContentCard.Content> 
</test:ContentCard> 
関連する問題