Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在Microsoft Dynamics CRM 2015中自定义选项卡页面选项卡,如流程箭头_C#_Winforms_Tabcontrol_System.drawing_Tabpage - Fatal编程技术网

C# 在Microsoft Dynamics CRM 2015中自定义选项卡页面选项卡,如流程箭头

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

我希望Windows窗体应用程序中的TabControl看起来像这样:

我有一个有流程的应用程序,每个选项卡页都是一个流程阶段,我想用这些漂亮的箭头来表示。我知道OnPaint和System.Drawing,但我无法使这些选项卡看起来像样

我试图处理TabControl.DrawItem事件并绘制箭头,但我对外观不满意

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);