Пользовательский GroupBox с круглыми краями

У меня есть вопрос об интерфейсе в визуальной студии, в C#. Я хочу, чтобы мой групповой ящик был похож на это:

Пример оформления GROUP BOX

и затем, я также хочу, чтобы расходы были зависят от разрешения экрана пользователя, поэтому размер группового блока не фиксирован, и мне нужно, чтобы он составлял, например, 80% экрана.

Так что мой вопрос на самом деле два вопроса:

  1. сделать костюм группы
  2. сделайте его на 80% (например) шириной экрана.

РЕДАКТИРОВАТЬ: благодаря этому ответу: Как сделать центр выравнивания текста групповой рамки в выигрышных формах? Мне удалось сделать то, что я хотел с цветами, теперь я просто скучаю по закругленным углам. есть идеи?

4 ответа

Решение

В качестве опции вы можете создать пользовательский элемент управления, вытекающий из GroupBox:

  • Вам нужно рассчитать прямоугольную форму. Для этого в качестве опции вы можете использовать AddArc метод и добавить дуги к четырем углам прямоугольника в пути.
  • Чтобы нарисовать фон заголовка в стиле штриховки, вы можете использовать HatchBrush, Поэтому добавьте свойство для стиля заголовка. Таким образом, вы можете использовать разные HatchStyle значения для названия фона.
  • Чтобы иметь другой цвет заголовка и шрифт заголовка, добавьте некоторые свойства для управления.
  • В более полной реализации вы должны реализовать свойства таким образом, чтобы установка нового значения для свойства вызывала перерисовку элемента управления путем вызова this.Invalidate(),
  • Чтобы предотвратить мерцание при изменении размера, включите двойную буферизацию, установив DoubleBuffered в true в конструкторе.
  • Чтобы иметь прозрачный фон в углах, используйте GroupBoxRenderer.DrawParentBackground, Скриншот

Код

using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
public class RoundPanel : GroupBox
{
    public RoundPanel()
    {
        this.DoubleBuffered = true;
        this.TitleBackColor = Color.SteelBlue;
        this.TitleForeColor = Color.White;
        this.TitleFont = new Font(this.Font.FontFamily, Font.Size + 8, FontStyle.Bold);
        this.BackColor = Color.Transparent;
        this.Radious = 25;
        this.TitleHatchStyle = HatchStyle.Percent60;
    }
    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        GroupBoxRenderer.DrawParentBackground(e.Graphics, this.ClientRectangle, this);
        var rect = ClientRectangle;
        using (var path = GetRoundRectagle(this.ClientRectangle, Radious))
        {
            e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
            rect = new Rectangle(0, 0,
                rect.Width, TitleFont.Height + Padding.Bottom + Padding.Top);
            if(this.BackColor!= Color.Transparent)
                using (var brush = new SolidBrush(BackColor))
                    e.Graphics.FillPath(brush, path);
            var clip = e.Graphics.ClipBounds;
            e.Graphics.SetClip(rect);
            using (var brush = new HatchBrush(TitleHatchStyle,
                TitleBackColor, ControlPaint.Light(TitleBackColor)))
                e.Graphics.FillPath(brush, path);
            using (var pen = new Pen(TitleBackColor, 1))
                e.Graphics.DrawPath(pen, path);
            TextRenderer.DrawText(e.Graphics, Text, TitleFont, rect, TitleForeColor);
            e.Graphics.SetClip(clip);
            using (var pen = new Pen(TitleBackColor, 1))
                e.Graphics.DrawPath(pen, path);
        }
    }
    public Color TitleBackColor { get; set; }
    public HatchStyle TitleHatchStyle { get; set; }
    public Font TitleFont { get; set; }
    public Color TitleForeColor { get; set; }
    public int Radious { get; set; }
    private GraphicsPath GetRoundRectagle(Rectangle b, int r)
    {
        GraphicsPath path = new GraphicsPath();
        path.AddArc(b.X, b.Y, r, r, 180, 90);
        path.AddArc(b.X + b.Width - r - 1, b.Y, r, r, 270, 90);
        path.AddArc(b.X + b.Width - r - 1, b.Y + b.Height - r - 1, r, r, 0, 90);
        path.AddArc(b.X, b.Y + b.Height - r - 1, r, r, 90, 90);
        path.CloseAllFigures();
        return path;
    }
}

Для WPF:

Вы можете создать Style сделать ваш GroupBox появляются по-другому.

Может быть, это может помочь вам в этом: Стилизация GroupBox

Для Windows Forms:

Чтобы изменить макет вы можете взглянуть на это: /questions/11476570/kak-sdelat-tsentr-vyiravnivaniya-teksta-gruppovogo-bloka-v-vyiigryishnyih-formah/11476578#11476578

Чтобы изменить размер GroupBox Вы можете использовать это:

System.Windows.SystemParameters.PrimaryScreenWidth
System.Windows.SystemParameters.PrimaryScreenHeight

GroupBox gb = new GroupBox();
gb.Width = (System.Windows.SystemParameters.PrimaryScreenWidth * 0.8) //Get your 80% ScreenWidth here.

Это чисто XAML-решение, без пользовательского элемента управления или кода. Он просто использует стандартную технику стиля / шаблона WPF. Обычно предпочтительнее использовать стили / шаблоны, а не пользовательские элементы управления.

Заголовок GroupBox может иметь другой размер, поэтому я добавил опцию изменения текста заголовка с помощью свойства "Tag" (в настоящее время установлено на 18).

Демо использования:

<GroupBox Style="{StaticResource GBStyled}" Tag="18" 
          Header="Hello" Height="150" Width="180">
    <TextBlock TextWrapping="Wrap">Text is different size to Header</TextBlock>
</GroupBox>

Определение стиля:

<Style x:Key="GBStyled" TargetType="GroupBox">
    <!-- These 2 setters make the GroupBox less blurry -->
    <Setter Property="SnapsToDevicePixels" Value="True"/>
    <Setter Property="UseLayoutRounding" Value="True"/>
    <!-- Default Background colour -->
    <Setter Property="Background" Value="White"/>
    <!-- Template of GroupBox -->
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="GroupBox">
                <ControlTemplate.Resources>
                    <!-- Custom hatched brush -->
                    <VisualBrush x:Key="MyVisualBrush" TileMode="Tile" Viewport="0,0,5,5" ViewportUnits="Absolute" Viewbox="0,0,15,15" ViewboxUnits="Absolute">
                        <VisualBrush.Visual>
                            <Grid Background="{StaticResource DarkBlueBrush}">
                                <Path Data="M 0 15 L 15 0" Stroke="White" />
                                <Path Data="M 0 0 L 15 15" Stroke="White" />
                            </Grid>
                        </VisualBrush.Visual>
                    </VisualBrush>
                </ControlTemplate.Resources>
                <Grid>
                    <Grid.Resources>
                    </Grid.Resources>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="*" />
                    </Grid.RowDefinitions>
                    <Border Grid.Row="0" CornerRadius="5,5,0,0" BorderThickness="1" BorderBrush="{StaticResource DarkBlueBrush}" Background="{StaticResource MyVisualBrush}">
                        <!-- FontSize of the header is changed via the Templates "Tag" property -->
                        <Label Foreground="White" FontSize="{Binding RelativeSource={RelativeSource AncestorType=GroupBox}, Path=Tag}" HorizontalAlignment="Center" FontWeight="Bold">
                            <!-- DropShadow makes the label standout from the background -->
                            <Label.Effect>
                                <DropShadowEffect ShadowDepth="0" BlurRadius="3" />
                            </Label.Effect>
                            <ContentPresenter Margin="0" ContentSource="Header" RecognizesAccessKey="True"/>
                        </Label>
                    </Border>
                    <Border Grid.Row="1" CornerRadius="0,0,5,5" BorderThickness="1,0,1,1" BorderBrush="{StaticResource DarkBlueBrush}" Background="{TemplateBinding Background}">
                        <ContentPresenter Margin="4" />
                    </Border>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Одним из вариантов является разработка собственного пользовательского элемента управления, полученного из GroupBox и переопределить OnPaint() способ сделать ваш рисунок.

public class CustomGroupBox : GroupBox
{
    protected override void OnPaint(PaintEventArgs e)
    {
        e.Graphics.FillRectangle(Brushes.Azure, this.ClientRectangle);
        //base.OnPaint(e);
    }

}

Новый элемент управления появится на панели инструментов после сборки автоматически.

Чтобы нарисовать этот объект DrawPath Метод может быть использован для рисования внешнего прямоугольника и FillPath Метод может быть использован для заполнения верхней панели.

https://msdn.microsoft.com/en-us/library/system.drawing.graphics.drawpath(v=vs.110).aspx

https://msdn.microsoft.com/en-us/library/system.drawing.graphics.fillpath(v=vs.110).aspx

Эластичный дизайн может быть сделан с TableLayoutPanel,

Другие вопросы по тегам