从右到左 TabControl c# 的 TabPages 的关闭按钮
Close button for TabPages of Right To Left TabControl c#
我想向 TabControl
的 TabPages
添加一个关闭按钮。我尝试了这段代码,它与从左到右的 TabControl 一起工作正常:
private Point _imageLocation = new Point(13, 5);
private Point _imgHitArea = new Point(13, 2);
this.tabControl2.DrawMode = System.Windows.Forms.TabDrawMode.OwnerDrawFixed;
tabControl2.DrawItem += TabControl2_DrawItem;
private void TabControl2_DrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e)
{
try
{
Image img = new Bitmap(GestionP.Properties.Resources.Close);
Rectangle r = e.Bounds;
r = this.tabControl2.GetTabRect(e.Index);
r.Offset(2, 2);
Brush TitleBrush = new SolidBrush(Color.Black);
Font f = this.Font;
string title = this.tabControl2.TabPages[e.Index].Text;
e.Graphics.DrawString(title, f, TitleBrush, new PointF(r.X, r.Y));
if (tabControl2.SelectedIndex >= 1)
{
e.Graphics.DrawImage(img, new Point(r.X + (this.tabControl2.GetTabRect(e.Index).Width - _imageLocation.X), _imageLocation.Y));
}
}
catch (Exception) { }
}
private void tabControl2_MouseClick(object sender, MouseEventArgs e)
{
TabControl tc = (TabControl)sender;
Point p = e.Location;
int _tabWidth = 0;
_tabWidth = this.tabControl2.GetTabRect(tc.SelectedIndex).Width - (_imgHitArea.X);
Rectangle r = this.tabControl2.GetTabRect(tc.SelectedIndex);
r.Offset(_tabWidth, _imgHitArea.Y);
r.Width = 16;
r.Height = 16;
if (tabControl2.SelectedIndex >= 1)
{
if (r.Contains(p))
{
TabPage TabP = (TabPage)tc.TabPages[tc.SelectedIndex];
tc.TabPages.Remove(TabP);
}
}
}
但是当我设置 属性 RightToLeftLayout = true
和 RightToLeft = true
时它不起作用,TabPage
标题没有出现,也没有关闭按钮。
那么如何以接受 RightToLeft
属性 的方式修复代码?
您可以创建一个函数来将矩形的坐标转换为容器中的 RTL 坐标:
public static Rectangle GetRTLCoordinates(Rectangle container, Rectangle drawRectangle)
{
return new Rectangle(
container.Width - drawRectangle.Width - drawRectangle.X,
drawRectangle.Y,
drawRectangle.Width,
drawRectangle.Height);
}
并且在RTL模式下绘画时,这样计算坐标:
tabRect = GetRTLCoordinates(this.tabControl2.ClientRectangle, tabRect);
此外,您应该使用 StringFormat
绘制字符串,并在处于 RTL 模式时将其设置为使用 StringFormatFlags.DirectionRightToLeft
,并使用字符串格式在转换后的矩形中绘制字符串:
e.Graphics.DrawString(this.tabControl2.TabPages[e.Index].Text,
this.Font, Brushes.Black, tabRect, sf);
可以将所有代码封装在一个CustomTabControl
继承TabControl
.
截图
整个代码可以是:
我想你有一个像 Properties.Default.Close
这样的接近图像并将它分配给 this.CloseImage
。这是我使用的图像:
我还设置了 this.tabControl2.Padding = new Point(10, 3);
以提供额外的免费 space 来绘制图像。
您也可以简单地添加不关闭第一个选项卡的条件。
Image CloseImage;
private void Form1_Load(object sender, EventArgs e)
{
this.tabControl2.DrawMode = System.Windows.Forms.TabDrawMode.OwnerDrawFixed;
tabControl2.DrawItem += TabControl2_DrawItem;
tabControl2.MouseClick += tabControl2_MouseClick;
CloseImage = Properties.Resources.Close;
this.tabControl2.Padding = new Point(10, 3);
}
private void TabControl2_DrawItem(object sender,
System.Windows.Forms.DrawItemEventArgs e)
{
try
{
var tabRect = this.tabControl2.GetTabRect(e.Index);
tabRect.Inflate(-2, -2);
var imageRect = new Rectangle(tabRect.Right - CloseImage.Width,
tabRect.Top + (tabRect.Height - CloseImage.Height) / 2,
CloseImage.Width,
CloseImage.Height);
var sf = new StringFormat(StringFormat.GenericDefault);
if (this.tabControl2.RightToLeft == System.Windows.Forms.RightToLeft.Yes &&
this.tabControl2.RightToLeftLayout == true)
{
tabRect = GetRTLCoordinates(this.tabControl2.ClientRectangle, tabRect);
imageRect = GetRTLCoordinates(this.tabControl2.ClientRectangle, imageRect);
sf.FormatFlags |= StringFormatFlags.DirectionRightToLeft;
}
e.Graphics.DrawString(this.tabControl2.TabPages[e.Index].Text,
this.Font, Brushes.Black, tabRect, sf);
e.Graphics.DrawImage(CloseImage, imageRect.Location);
}
catch (Exception) { }
}
private void tabControl2_MouseClick(object sender, MouseEventArgs e)
{
for (var i = 0; i < this.tabControl2.TabPages.Count; i++)
{
var tabRect = this.tabControl2.GetTabRect(i);
tabRect.Inflate(-2, -2);
var imageRect = new Rectangle(tabRect.Right - CloseImage.Width,
tabRect.Top + (tabRect.Height - CloseImage.Height) / 2,
CloseImage.Width,
CloseImage.Height);
if (imageRect.Contains(e.Location))
{
this.tabControl2.TabPages.RemoveAt(i);
break;
}
}
}
public static Rectangle GetRTLCoordinates(Rectangle container, Rectangle drawRectangle)
{
return new Rectangle(
container.Width - drawRectangle.Width - drawRectangle.X,
drawRectangle.Y,
drawRectangle.Width,
drawRectangle.Height);
}
不需要重写绘图:
1. select 选项卡控件。
2. 将 RightToLeft
属性 设置为 yes
AND RightToLeftLayout
属性 为 true
.
现在所有的标签页都是从右到左对齐的(诀窍是 RightToLeft
和 RightToLeftLayout
属性必须设置为已更改,不知道微软为什么那样做...)
我想向 TabControl
的 TabPages
添加一个关闭按钮。我尝试了这段代码,它与从左到右的 TabControl 一起工作正常:
private Point _imageLocation = new Point(13, 5);
private Point _imgHitArea = new Point(13, 2);
this.tabControl2.DrawMode = System.Windows.Forms.TabDrawMode.OwnerDrawFixed;
tabControl2.DrawItem += TabControl2_DrawItem;
private void TabControl2_DrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e)
{
try
{
Image img = new Bitmap(GestionP.Properties.Resources.Close);
Rectangle r = e.Bounds;
r = this.tabControl2.GetTabRect(e.Index);
r.Offset(2, 2);
Brush TitleBrush = new SolidBrush(Color.Black);
Font f = this.Font;
string title = this.tabControl2.TabPages[e.Index].Text;
e.Graphics.DrawString(title, f, TitleBrush, new PointF(r.X, r.Y));
if (tabControl2.SelectedIndex >= 1)
{
e.Graphics.DrawImage(img, new Point(r.X + (this.tabControl2.GetTabRect(e.Index).Width - _imageLocation.X), _imageLocation.Y));
}
}
catch (Exception) { }
}
private void tabControl2_MouseClick(object sender, MouseEventArgs e)
{
TabControl tc = (TabControl)sender;
Point p = e.Location;
int _tabWidth = 0;
_tabWidth = this.tabControl2.GetTabRect(tc.SelectedIndex).Width - (_imgHitArea.X);
Rectangle r = this.tabControl2.GetTabRect(tc.SelectedIndex);
r.Offset(_tabWidth, _imgHitArea.Y);
r.Width = 16;
r.Height = 16;
if (tabControl2.SelectedIndex >= 1)
{
if (r.Contains(p))
{
TabPage TabP = (TabPage)tc.TabPages[tc.SelectedIndex];
tc.TabPages.Remove(TabP);
}
}
}
但是当我设置 属性 RightToLeftLayout = true
和 RightToLeft = true
时它不起作用,TabPage
标题没有出现,也没有关闭按钮。
那么如何以接受 RightToLeft
属性 的方式修复代码?
您可以创建一个函数来将矩形的坐标转换为容器中的 RTL 坐标:
public static Rectangle GetRTLCoordinates(Rectangle container, Rectangle drawRectangle)
{
return new Rectangle(
container.Width - drawRectangle.Width - drawRectangle.X,
drawRectangle.Y,
drawRectangle.Width,
drawRectangle.Height);
}
并且在RTL模式下绘画时,这样计算坐标:
tabRect = GetRTLCoordinates(this.tabControl2.ClientRectangle, tabRect);
此外,您应该使用 StringFormat
绘制字符串,并在处于 RTL 模式时将其设置为使用 StringFormatFlags.DirectionRightToLeft
,并使用字符串格式在转换后的矩形中绘制字符串:
e.Graphics.DrawString(this.tabControl2.TabPages[e.Index].Text,
this.Font, Brushes.Black, tabRect, sf);
可以将所有代码封装在一个CustomTabControl
继承TabControl
.
截图
整个代码可以是:
我想你有一个像 Properties.Default.Close
这样的接近图像并将它分配给 this.CloseImage
。这是我使用的图像:
我还设置了 this.tabControl2.Padding = new Point(10, 3);
以提供额外的免费 space 来绘制图像。
您也可以简单地添加不关闭第一个选项卡的条件。
Image CloseImage;
private void Form1_Load(object sender, EventArgs e)
{
this.tabControl2.DrawMode = System.Windows.Forms.TabDrawMode.OwnerDrawFixed;
tabControl2.DrawItem += TabControl2_DrawItem;
tabControl2.MouseClick += tabControl2_MouseClick;
CloseImage = Properties.Resources.Close;
this.tabControl2.Padding = new Point(10, 3);
}
private void TabControl2_DrawItem(object sender,
System.Windows.Forms.DrawItemEventArgs e)
{
try
{
var tabRect = this.tabControl2.GetTabRect(e.Index);
tabRect.Inflate(-2, -2);
var imageRect = new Rectangle(tabRect.Right - CloseImage.Width,
tabRect.Top + (tabRect.Height - CloseImage.Height) / 2,
CloseImage.Width,
CloseImage.Height);
var sf = new StringFormat(StringFormat.GenericDefault);
if (this.tabControl2.RightToLeft == System.Windows.Forms.RightToLeft.Yes &&
this.tabControl2.RightToLeftLayout == true)
{
tabRect = GetRTLCoordinates(this.tabControl2.ClientRectangle, tabRect);
imageRect = GetRTLCoordinates(this.tabControl2.ClientRectangle, imageRect);
sf.FormatFlags |= StringFormatFlags.DirectionRightToLeft;
}
e.Graphics.DrawString(this.tabControl2.TabPages[e.Index].Text,
this.Font, Brushes.Black, tabRect, sf);
e.Graphics.DrawImage(CloseImage, imageRect.Location);
}
catch (Exception) { }
}
private void tabControl2_MouseClick(object sender, MouseEventArgs e)
{
for (var i = 0; i < this.tabControl2.TabPages.Count; i++)
{
var tabRect = this.tabControl2.GetTabRect(i);
tabRect.Inflate(-2, -2);
var imageRect = new Rectangle(tabRect.Right - CloseImage.Width,
tabRect.Top + (tabRect.Height - CloseImage.Height) / 2,
CloseImage.Width,
CloseImage.Height);
if (imageRect.Contains(e.Location))
{
this.tabControl2.TabPages.RemoveAt(i);
break;
}
}
}
public static Rectangle GetRTLCoordinates(Rectangle container, Rectangle drawRectangle)
{
return new Rectangle(
container.Width - drawRectangle.Width - drawRectangle.X,
drawRectangle.Y,
drawRectangle.Width,
drawRectangle.Height);
}
不需要重写绘图:
1. select 选项卡控件。
2. 将 RightToLeft
属性 设置为 yes
AND RightToLeftLayout
属性 为 true
.
现在所有的标签页都是从右到左对齐的(诀窍是 RightToLeft
和 RightToLeftLayout
属性必须设置为已更改,不知道微软为什么那样做...)