Пользовательский GroupBox с круглыми краями
У меня есть вопрос об интерфейсе в визуальной студии, в C#. Я хочу, чтобы мой групповой ящик был похож на это:
и затем, я также хочу, чтобы расходы были зависят от разрешения экрана пользователя, поэтому размер группового блока не фиксирован, и мне нужно, чтобы он составлял, например, 80% экрана.
Так что мой вопрос на самом деле два вопроса:
- сделать костюм группы
- сделайте его на 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
,