WPF Cut Угловой элемент - PullRequest
5 голосов
/ 23 июня 2011

Я пытаюсь создать что-то похожее на изображение ниже в WPF.Этот элемент управления предназначен для базового просмотра всего в моем приложении и будет находиться в элементе управления Window с фоном (возможно, некоторого градиента).

Требования следующие:

  • Закругленные углы с трех сторон (верхний левый, нижний левый и нижний правый)
  • Вырезать угол в виде вкладки в верхней правой части, фон которого за прозрачной "областью выреза" прозрачен, поэтому фоновый градиентиз окна показывает (выглядит так, будто оно действительно обрезано)
  • Область заголовка должна быть контейнером содержимого, чтобы я мог поместить в нее все, что угодно, например значки и текст
  • Область содержимого должнаиметь минимальную высоту, а затем увеличиваться, если внутреннее содержимое превышает его (не на лету - просто поддерживайте высоту всех элементов, находящихся в нем)

Я боролся с этим часами, нобудучи новичком в WPF, я начинаю бегать кругами.Я думаю, что гибкость WPF имеет большие преимущества, но для людей, только начинающих, это почти слишком сложно.

Любая помощь будет высоко ценится!Спасибо!

Content Layout

Ответы [ 3 ]

4 голосов
/ 24 июня 2011

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>
4 голосов
/ 24 июня 2011

Попробуйте, чтобы начать:

<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 голосов
/ 24 июня 2011

Вот код, который я собрал, используя пользовательский элемент управления.

Контрольный код:

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

Control xaml (в папке Themes / 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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...