2011-06-23 43 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>