Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/293.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# 使用Graphics.DrawImage在C中创建自定义选项卡_C#_Tabs - Fatal编程技术网

C# 使用Graphics.DrawImage在C中创建自定义选项卡

C# 使用Graphics.DrawImage在C中创建自定义选项卡,c#,tabs,C#,Tabs,我有一个项目,在这个项目中,你可以像web浏览器一样添加和删除选项卡。到目前为止,我有: //Button to add a new tab page private void cb_addPage_Click(object sender, EventArgs e) { string title = "TabPage " + (tabControl1.TabCount + 1).ToString() + " "; TabPage myTabPa

我有一个项目,在这个项目中,你可以像web浏览器一样添加和删除选项卡。到目前为止,我有:

//Button to add a new tab page
    private void cb_addPage_Click(object sender, EventArgs e)
    {
        string title = "TabPage " + (tabControl1.TabCount + 1).ToString() + "   ";
        TabPage myTabPage = new TabPage(title);
        tabControl1.TabPages.Add(myTabPage);
        tabControl1.SelectedTab = myTabPage;
    }


//Form1_Load
    private void Form1_Load(object sender, EventArgs e)
    {
        tabControl1.DrawMode = TabDrawMode.OwnerDrawFixed;
        cb_addPage.Top = tabControl1.Top;
        cb_addPage.Left = tabControl1.Right - cb_addPage.Width;
        foreach (TabPage tp in tabControl1.TabPages) tp.Text += "   ";
    }

    Rectangle closeX = Rectangle.Empty;

//Sets background and places the X button on each tab
    private void tabControl1_DrawItem(object sender, DrawItemEventArgs e)
    {
        Size xSize = new Size(15, 15);
        TabPage tp = tabControl1.TabPages[e.Index];
        e.DrawBackground();
        using (SolidBrush brush = new SolidBrush(e.ForeColor))
            e.Graphics.DrawString(tp.Text + "   ", e.Font, brush,
                                  e.Bounds.X + 3, e.Bounds.Y + 4);

        if (e.State == DrawItemState.Selected)
        {
            closeX = new Rectangle(e.Bounds.Right - xSize.Width - 3, 
                           e.Bounds.Top + 5, xSize.Width, xSize.Height);
            e.Graphics.DrawImage(imageList1.Images[0], closeX, 
                         new Rectangle(0,0,16,16), GraphicsUnit.Pixel );
        }

    }

//Removes current tab (from X button)
    private void tabControl1_MouseClick(object sender, MouseEventArgs e)
    {
        if (closeX.Contains(e.Location))
            tabControl1.TabPages.Remove(tabControl1.SelectedTab);
    }
因此,所有这一切都是让你添加一个按钮选项卡和每个单独的标签上有一个X按钮删除标签

我使用Graphics.DrawImage来显示imageList中的自定义X按钮。但是,我将如何使用Graphics.DrawImage制作自定义选项卡


总而言之,我想要标签,但我希望它们是我制作的自定义图像,这样看起来更好。-谢谢你的问题不是很清楚。您可能希望在每个选项卡上显示不同的文本。您可以使用TextRenderer执行此操作:

const TextFormatFlags flags = TextFormatFlags.PreserveGraphicsClipping |
    TextFormatFlags.VerticalCenter;

TextRenderer.DrawText(e.Graphics, tp.Text, tp.Font, e.Bounds, tp.ForeColor, flags);
在文本前面加上一些空格,以便为X留出空间,或者为文本定义新的坐标

const int XCrossWidth = 20;
Rectangle textRect = new Rectangle(e.Bounds.Left + XCrossWidth,  e.Bounds.Top,
                                   e.Width - XCrossWidth, e.Height);
并将其替换为TextRenderer.DrawText中的e.Bounds

更新

因此,您希望在选项卡上显示自定义图像。我假设您已将这些图像放置在imageList1中。您如何知道要在哪个选项卡页上显示其中的哪一个

您可以创建自己的tab page类,并使用此类而不是TabPage

现在将属性设置为适当的图像索引

TabPageEx myTabPage = new TabPageEx(title);
myTabPage.ImageIndex = 3; // As an example.
tabControl1.TabPages.Add(myTabPage);
然后,您可以使用

TabPageEx tp = (TabPageEx)tabControl1.TabPages[e.Index];

...

Rectangle imageRect = new Rectangle(e.Bounds.Left + 20,  0, 16, 16);
e.Graphics.DrawImage(imageList1.Images[tp.ImageIndex], imageRect);

如果要显示除文本外的图像,如webbrowsers favicon,则可以使用此修改后的代码:

private void tabControl3_DrawItem(object sender, DrawItemEventArgs e)
{
    Size xSize = new Size(16,16);
    Point imgLoc = new Point(e.Bounds.X +  4, e.Bounds.Y + 4);
    TabPage tp = tabControl3.TabPages[e.Index];
    e.DrawBackground();
    e.Graphics.DrawImage(imageList1.Images[tp.ImageIndex], new Rectangle(imgLoc, xSize), 
                            new Rectangle(Point.Empty, xSize), GraphicsUnit.Pixel);

    using (SolidBrush brush = new SolidBrush(e.ForeColor))
    {
        e.Graphics.DrawString(tp.Text + "   ", e.Font, brush, 
                              e.Bounds.X + 23, e.Bounds.Y + 4);
        if (e.State == DrawItemState.Selected)
        {
            closeX = new Rectangle(e.Bounds.Right - xSize.Width - 3, 
                         e.Bounds.Top + 5, xSize.Width, xSize.Height);
            e.Graphics.DrawImage(imageList1.Images[0], closeX, 
                       new Rectangle(Point.Empty, xSize), GraphicsUnit.Pixel);

        }
    }
}
您需要确保:

在imagelist的每个选项卡中都有要显示的图像。 你知道ech一号的指数。 您必须在创建页面时设置它,但您可以随时在以后更改它。 最好在索引0处有一个默认图标,并为不知道正确索引的用户将imageindex设置为0。 通常,您还必须使选项卡控件指向Imagelist。但既然我们都是自己画的,这就不重要了

您可以使用更复杂的DrawString格式,即用于绘制关闭按钮的格式。在这里,你不只是使用一个点来确定绘制的位置;相反,这种格式使用两个矩形来确定源和目标。这有效地导致了将图像缩放到新大小的选项


但是如果你的图像一开始就有合适的尺寸,你会得到最好的质量。请注意,每个选项卡页的文本决定了选项卡的宽度;要使其更高,您需要选择更大的字体大小。

结尾处编辑了摘要。啊,对了,我有一张135 x 30的图片,如下所示:。忽略上面的文字,这是为了测试。但这是图片,我想知道我是否可以用每个标签的图片替换标签。您还知道我将把e.Graphics.DrawImageimageList2.Images[e.Index],Point.Empty;,放在哪里吗;?我不能100%确定它在我的代码中会出现在哪里。好吧,30像素的高度有点高。但是你真的想为每个选项卡显示这些图像吗如果所有的图片都只显示文本,你也可以改变字体来匹配图片中的字体;那会容易得多,当然也很灵活。。背景是为文本创建的siple,tooWell,我打算用它进行测试。我可以很快地创建一个80 x 15或类似Verdana的字体。如果你把标签控件的字体改为Verdana 12-15点,你只需要添加一个圆角矩形。哦,对了,我的最终目标是在标签中显示页面上的内容,就像一个web浏览器一样,但我想尝试一下,然后弄清楚,但是如果字体和文本起到了很大的作用,现在值得尝试吗?如果是这样,是否必须在选项卡上显示文本框,然后将其链接到页面上的某个字符串?
private void tabControl3_DrawItem(object sender, DrawItemEventArgs e)
{
    Size xSize = new Size(16,16);
    Point imgLoc = new Point(e.Bounds.X +  4, e.Bounds.Y + 4);
    TabPage tp = tabControl3.TabPages[e.Index];
    e.DrawBackground();
    e.Graphics.DrawImage(imageList1.Images[tp.ImageIndex], new Rectangle(imgLoc, xSize), 
                            new Rectangle(Point.Empty, xSize), GraphicsUnit.Pixel);

    using (SolidBrush brush = new SolidBrush(e.ForeColor))
    {
        e.Graphics.DrawString(tp.Text + "   ", e.Font, brush, 
                              e.Bounds.X + 23, e.Bounds.Y + 4);
        if (e.State == DrawItemState.Selected)
        {
            closeX = new Rectangle(e.Bounds.Right - xSize.Width - 3, 
                         e.Bounds.Top + 5, xSize.Width, xSize.Height);
            e.Graphics.DrawImage(imageList1.Images[0], closeX, 
                       new Rectangle(Point.Empty, xSize), GraphicsUnit.Pixel);

        }
    }
}