具有圆边的自定义 GroupBox
Custom GroupBox with round edges
我对 C# 中的 visual studio 中的 UI 有疑问。我想让我的组框自定义看起来像这样:
然后,我还希望它根据用户的屏幕分辨率来扩展,所以组框的大小不是固定的,我需要它例如是屏幕的 80%。
所以我的问题实际上是两个问题:
- 制作groupbox服装
- 使其成为屏幕宽度的 80%(例如)。
编辑:感谢这个答案:
我设法用颜色做了我想做的,现在我只是缺少圆角。有什么想法吗?
对于 WPF:
您可以创建一个 Style
让您的 GroupBox
以不同的方式出现。
也许这可以帮助你:Styling a GroupBox
对于Windows 表格:
要更改布局,您可以查看以下内容:
要调整 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.
一种选择是开发您自己的派生自 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
来完成。
作为一个选项,您可以创建一个派生自 GroupBox
:
的自定义控件
- 您需要计算一个圆角矩形。为此,您可以选择使用
AddArc
方法并将圆弧添加到路径中矩形的四个角。
- 要使用剖面线样式绘制 header 背景,您可以为标题 back-ground 使用
HatchBrush
. So add a property for title hatch style. This way you can use different 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;
}
}
这是一个纯粹的 XAML 解决方案,没有自定义控件或代码。它只是使用标准的 WPF style/template 技术。通常最好使用 styles/templates 而不是自定义控件。
GroupBox header 的大小可以不同,因此我添加了使用 "Tag" 属性(当前设置为 18)更改 header 文本的选项。
使用演示:
<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>
我对 C# 中的 visual studio 中的 UI 有疑问。我想让我的组框自定义看起来像这样:
然后,我还希望它根据用户的屏幕分辨率来扩展,所以组框的大小不是固定的,我需要它例如是屏幕的 80%。
所以我的问题实际上是两个问题:
- 制作groupbox服装
- 使其成为屏幕宽度的 80%(例如)。
编辑:感谢这个答案:
对于 WPF:
您可以创建一个 Style
让您的 GroupBox
以不同的方式出现。
也许这可以帮助你:Styling a GroupBox
对于Windows 表格:
要更改布局,您可以查看以下内容:
要调整 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.
一种选择是开发您自己的派生自 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
来完成。
作为一个选项,您可以创建一个派生自 GroupBox
:
- 您需要计算一个圆角矩形。为此,您可以选择使用
AddArc
方法并将圆弧添加到路径中矩形的四个角。 - 要使用剖面线样式绘制 header 背景,您可以为标题 back-ground 使用
HatchBrush
. So add a property for title hatch style. This way you can use differentHatchStyle
值。 - 要有不同的标题颜色和标题字体,请添加一些属性来控制。
- 在更完整的实现中,您应该以将新值设置为 属性 的方式实现属性,从而通过调用
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;
}
}
这是一个纯粹的 XAML 解决方案,没有自定义控件或代码。它只是使用标准的 WPF style/template 技术。通常最好使用 styles/templates 而不是自定义控件。
GroupBox header 的大小可以不同,因此我添加了使用 "Tag" 属性(当前设置为 18)更改 header 文本的选项。
使用演示:
<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>