2011-06-23 46 views
5

我正嘗試在WPF中創建類似於下圖的東西。這個控件被設計成在我的應用程序中的所有東西的基本視圖,並且將坐在帶有背景的窗口控件(可能是某種類型的漸變)中。WPF切角元素

的要求如下:

  • 三面(左上,左下和右下)圓角
  • 剪去頂部右側標籤尋找角落背後都有後臺「剪切區域「透明,使窗口背景漸變顯示(使它看起來像它真的被切斷)
  • 標題區域應該是一個內容容器,所以我可以把任何東西,如圖標和文字
  • 內容區域需要有一個最低限度高度,然後增長,如果內在的內容超過它(不是在飛行中 - 只是支持任何元素的高度)

我一直與這個戰鬥了幾個小時,但對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中重新看到一個問題......您是如何在世界上學會如何提出您所做的事情的?真正以有用的方式學習WPF的資源似乎非常稀缺。 – RubyHaus

+0

五年前,我做了你現在所處的困難部分。我閱讀這些書籍,編寫了多個項目,犯了錯誤,並問了其他人(當時並沒有那麼多人,但我有幸能夠接觸到一些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))); 
     } 
    } 
} 

控制XAML(可在主題/ Generic.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>