Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/322.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# 如何在WindowsForms Picturebox上绘制字符串?_C#_Winforms_Graphics_Bitmap - Fatal编程技术网

C# 如何在WindowsForms Picturebox上绘制字符串?

C# 如何在WindowsForms Picturebox上绘制字符串?,c#,winforms,graphics,bitmap,C#,Winforms,Graphics,Bitmap,我有自己的简单3d引擎类(myGraphics),它将结果保存在位图变量中。 然后将该位图放置在PictureBox中(PictureBox.Image=myGraphics.bmp) 这是工作得很好,问题来了,当我需要在图纸上标记一些点。由于没有内置的方法在位图上绘制字符串,我遵循了类似问题的解决方案,现在我在myGraphics上得到了一个Graphics变量,因此我可以在那里绘制数字。代码的重要部分如下所示: public class myGraphics { public Gra

我有自己的简单3d引擎类(
myGraphics
),它将结果保存在位图变量中。 然后将该位图放置在PictureBox中(
PictureBox.Image=myGraphics.bmp

这是工作得很好,问题来了,当我需要在图纸上标记一些点。由于没有内置的方法在位图上绘制字符串,我遵循了类似问题的解决方案,现在我在
myGraphics
上得到了一个
Graphics
变量,因此我可以在那里绘制数字。代码的重要部分如下所示:

public class myGraphics
{
    public Graphics g;
    public void initialize(int W, int H )
    {
        //sets some values 
        g = Graphics.FromImage(bmp);
        g.SmoothingMode = SmoothingMode.AntiAlias;
        g.InterpolationMode = InterpolationMode.HighQualityBicubic;
        g.PixelOffsetMode = PixelOffsetMode.HighQuality;
    }
    public void draw()
    {
        // code to draw on myGraphics.bmp
        markpoints();
    }
    public void markpoints() 
    {
        if (draw_points) { 
            foreach (objecto ob in solidos) {
                for (int p = 0; p < ob.viewpoints.Count; p++)
                {
                    // determine position of text (x, y)
                    SolidBrush drawBrush = new SolidBrush(Color.Black);
                    g.DrawString(p.ToString(), new Font("Arial", 10), drawBrush, x, y);
                    g.Flush();
                }
            }
        }
    }
公共类myGraphics
{
公共图形g;
公共无效初始化(整数W,整数H)
{
//设置一些值
g=图形。来自图像(bmp);
g、 SmoothingMode=SmoothingMode.AntiAlias;
g、 插值模式=插值模式。高质量双三次;
g、 PixelOffsetMode=PixelOffsetMode.HighQuality;
}
公众抽签()
{
//在myGraphics.bmp上绘制的代码
标记点();
}
公共无效标记点()
{
如果(绘制点){
foreach(以solidos表示的对象对象){
for(int p=0;p
现在,如果我做对了,g.Flush()应该合并位图上的图形g,但它不是这样工作的,所以我得到了正确的图像,但没有刺痛

我还尝试了以下方法:
myGraphics.g=PictureBox.CreateGraphics();
来解决这个问题。在调试模式下使用断点,我意识到字符串确实会使用此方法显示在控件上,但在PictureBox更新后会立即被删除


那么,我该如何解决这个问题,才能得到图形上显示的数字呢?

当更新
PictureBox.Image
时,图形将被清除。因此,必须在更新
PictureBox.Image
之后,从类外调用
markpoints()

另外,分配
myGraphics.g=Picturebox.CreateGraphics()
无效,myGraphics.g上的更改将不会更新到控件Picturebox。控件的图形必须在绘制事件时更新,并将
e.graphics
传递到
标记点

另外,
g.flush()
不会将图形与位图合并,这段代码实际上没有必要

因此,最终的解决方案是:

public class myGraphics
{
    // public Graphics g is no longer necessary
    public void initialize(int W, int H ) { //sets some values}
    public void draw() { // code to draw on myGraphics.bmp }

    public void markpoints(Graphics graph) 
    {
        if (draw_points) { 
            graph.SmoothingMode = SmoothingMode.AntiAlias;
            graph.InterpolationMode = InterpolationMode.HighQualityBicubic;
            graph.PixelOffsetMode = PixelOffsetMode.HighQuality;

            foreach (objecto ob in solidos) {
                for (int p = 0; p < ob.viewpoints.Count; p++)
                {
                    // determine position of text (x, y)
                    SolidBrush drawBrush = new SolidBrush(Color.Black);
                    g.DrawString(p.ToString(), new Font("Arial", 10), drawBrush, x, y);
                }
            }
        }
    }
}

// Connect to picture box
myGraphics mg = new myGraphics()
Picturebox.Image = mg.bmp;
PictureBox.Invalidate(); // forces update of the control using paint event

private void PictureBox_Paint(object sender, PaintEventArgs e) 
{
    mg.markpoints(e.Graphics);
}
公共类myGraphics
{
//不再需要公共图形g
公共void初始化(intw,inth){//设置一些值}
public void draw(){//在myGraphics.bmp上绘制的代码}
公共空心标记点(图形)
{
如果(绘制点){
graph.SmoothingMode=SmoothingMode.AntiAlias;
graph.InterpolationMode=InterpolationMode.HighQualityBicubic;
graph.PixelOffsetMode=PixelOffsetMode.HighQuality;
foreach(以solidos表示的对象对象){
for(int p=0;p
您正在修改位图,但PictureBox无法知道这一点。Image类没有事件。因此它不知道需要重新绘制图像。这取决于您是否调用PictureBox“Invalidate()方法,现在它知道了。这不是问题所在,但它让我明白了,所以谢谢。这是一个愚蠢的错误,我仍然会用PictureBox.CreateGraphics()编写一个答案足以解决问题不,很可能这还不够,因为结果不会持续..要么绘制到图像中,要么使用绘画事件中的e.Graphics对象..@TaW我无法分配
e.Graphics()=myGraphics.g
,因为
e.Graphics
是只读的…这是否意味着我必须放置
标记点()
paint事件中的代码?是。或者您可以将
e.Graphics
对象传递给使用它进行绘图的函数,例如
markpoints(e.Graphics)
。请注意,必须从
Paint
事件调用此函数,不允许存储或缓存它,否则它将无效!谢谢,它工作正常,性能也更好。我是否应该更新我的答案?我是新来的,所以。。。