C# 在Microsoft Dynamics CRM 2015中自定义选项卡页面选项卡,如流程箭头
我希望Windows窗体应用程序中的TabControl看起来像这样: 我有一个有流程的应用程序,每个选项卡页都是一个流程阶段,我想用这些漂亮的箭头来表示。我知道OnPaint和System.Drawing,但我无法使这些选项卡看起来像样 我试图处理TabControl.DrawItem事件并绘制箭头,但我对外观不满意C# 在Microsoft Dynamics CRM 2015中自定义选项卡页面选项卡,如流程箭头,c#,winforms,tabcontrol,system.drawing,tabpage,C#,Winforms,Tabcontrol,System.drawing,Tabpage,我希望Windows窗体应用程序中的TabControl看起来像这样: 我有一个有流程的应用程序,每个选项卡页都是一个流程阶段,我想用这些漂亮的箭头来表示。我知道OnPaint和System.Drawing,但我无法使这些选项卡看起来像样 我试图处理TabControl.DrawItem事件并绘制箭头,但我对外观不满意 private void tabControl1_DrawItem(object sender, DrawItemEventArgs e) { Rectangle re
private void tabControl1_DrawItem(object sender, DrawItemEventArgs e)
{
Rectangle rect = e.Bounds;
int offset = 10;
Point p1 = e.Bounds.Location;
Point p2 = new Point(e.Bounds.X + e.Bounds.Width - offset, e.Bounds.Y);
Point p3 = new Point(e.Bounds.X + e.Bounds.Width, e.Bounds.Y + (e.Bounds.Height / 2));
Point p4 = new Point(p2.X, e.Bounds.Bottom);
Point p5 = new Point(e.Bounds.X, e.Bounds.Y+e.Bounds.Height);
Point p6 = new Point(e.Bounds.X + offset, p3.Y);
GraphicsPath path = new GraphicsPath();
path.AddLine(p1, p2);
path.AddLine(p2, p3);
path.AddLine(p3, p4);
path.AddLine(p4, p5);
path.AddLine(p5, p6);
path.AddLine(p6, p1);
e.Graphics.FillPath(Brushes.Black, path);
};
有没有其他方法可以使这项工作如所述?有时我会发疯,只是为了好玩而接受挑战:-) 结果如下: 我用
面板tp
覆盖选项卡控制选项卡控制1
。(请选择更好的名称!)请注意,这必须发生得很晚,否则TabControl
将弹出到顶部
我在所示的事件中调用它们进行排序:
private void Form1_Shown(object sender, EventArgs e)
{
tp.BringToFront();
tabControl1.SendToBack();
}
您可能可以在设计器中创建面板
,以避免这些运动
除了面板
之外,我还需要一个列表
,用于绘图和精确命中测试
Panel tp = null;
List<GraphicsPath> tabAreas = new List<GraphicsPath>();
在此之后,实际事件相当简单:
void tp_MouseClick(object sender, MouseEventArgs e)
{
for (int t = 0; t < tabAreas.Count; t++)
{
if (tabAreas[t].IsVisible(e.Location) )
{ tabControl1.SelectedIndex = t; break;}
}
tp.Invalidate();
}
void tp_Paint(object sender, PaintEventArgs e)
{
StringFormat fmt = new StringFormat()
{ Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center };
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.Clear(Color.White); // **
float w = tp.Width / tabAreas.Count;
Size sz = new System.Drawing.Size( (int)w, e.ClipRectangle.Height);
for (int t = 0; t < tabAreas.Count; t++)
{
Rectangle rect = new Rectangle((int)(t * w ), 0, sz.Width, sz.Height);
bool selected = tabControl1.SelectedIndex == t ;
Brush brush = selected ? Brushes.DarkGoldenrod : Brushes.DarkGray; // **
e.Graphics.FillPath(brush, tabAreas[t]);
e.Graphics.DrawString(tabControl1.TabPages[t].Text,
tabControl1.Font, Brushes.White, rect, fmt);
}
}
我怀疑你能否摆脱分隔条。因此,即使你正确地绘制标签,也永远不会得到那种很酷的交错外观,即重叠三角形的颜色正确。-恐怕您需要用自定义绘制的面板覆盖整个选项卡,并捕捉鼠标单击,将它们映射到选项卡上..我找到了这篇好文章:并将我的代码放入TabStyleChromeProvider.AddTabBorder方法中。结果非常令人鼓舞。我想在这方面得到一些帮助。我想我们可以让这种风格看起来像那些流程箭头。很有趣,但我不认为我会进入它。。听起来它比你实际需要的要多得多,并且使用了更多的代码行你有没有看过我的代码示例..?抽绳?你知道它被替换了(除了打印)。哦,“替换”有点夸张。拉绳很好用。我只是对手头的案例进行了逐像素比较,不太确定我更喜欢TextRenderer稍微宽一点的结果。(你自己看!)-但是它有更多的选择,所以,一定要记住一个改进,特别是因为TextFormatFlags得到了极大的扩展。Hi-TaW!哇,从照片上看,这看起来太棒了!谢谢你!我只是无法在我的简单测试表上实现这一点。我将TabControl放在了3个选项卡上,在InitializeComponent之后称为makeTabPanel,然后添加了Showed事件处理程序,但该面板从未显示,也从未调用过Paint,所以我看到了经典的TabControl。另一件事:“sz”变量没有声明,我不知道它的大小。EDIT:我以所示的形式调用makeTabPanel,因为在显示控件之前ItemSize属性是0。现在它工作得很好!再次非常感谢!我将尝试使用户控制从这个。有什么原因为什么标签闪烁时,改变选择?我在Paint handler中没有看到任何繁重的操作,有一个Brush对象和FillPath、DrawString调用。我将DoubleBuffered属性设置为true,但它是相同的。我认为最后一个选项卡闪烁最多(在我的示例中有3个选项卡)
void tp_MouseClick(object sender, MouseEventArgs e)
{
for (int t = 0; t < tabAreas.Count; t++)
{
if (tabAreas[t].IsVisible(e.Location) )
{ tabControl1.SelectedIndex = t; break;}
}
tp.Invalidate();
}
void tp_Paint(object sender, PaintEventArgs e)
{
StringFormat fmt = new StringFormat()
{ Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center };
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.Clear(Color.White); // **
float w = tp.Width / tabAreas.Count;
Size sz = new System.Drawing.Size( (int)w, e.ClipRectangle.Height);
for (int t = 0; t < tabAreas.Count; t++)
{
Rectangle rect = new Rectangle((int)(t * w ), 0, sz.Width, sz.Height);
bool selected = tabControl1.SelectedIndex == t ;
Brush brush = selected ? Brushes.DarkGoldenrod : Brushes.DarkGray; // **
e.Graphics.FillPath(brush, tabAreas[t]);
e.Graphics.DrawString(tabControl1.TabPages[t].Text,
tabControl1.Font, Brushes.White, rect, fmt);
}
}
TextFormatFlags flags = TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter ;
TextRenderer.DrawText(e.Graphics, tabControl1.TabPages[t].Text,
tabControl1.Font, rect, Color.White, flags);