Graphics.DrawString не работает

Я хочу нарисовать текст над PictureBox в цикле foreach. Это код, который отвечает за рендеринг (GG — это PictureBox, который в данный момент находится в цикле)

if (GG != null)
      {
            ((PictureBox)GG).Image = (Image)obj;
            using (Graphics g = ((PictureBox)GG).CreateGraphics()) {
            g.DrawString(i["amount"].ToString(), kryptonRichTextBox1.Font, 
            new SolidBrush(Color.Gold), new Point(16, 18));
      }

}

Но, к сожалению, текст не отображается. Если я закомментирую

//((PictureBox)GG).Image = (Image)obj;

линия, это работает! Я понятия не имею, как заставить его работать.

Я хотел использовать TextRenderer, но я не знаю, как получить IDeviceContext элемента управления (и все примеры, которые я вижу в Интернете, используют PaintEventArgs.Graphics в событии Paint).

Кроме того, если это уместно, GG PictureBox является дочерним элементом другого изображения и имеет прозрачный фон.

Я попытался обновить окно после аннулирования рабочего кода:

if (GG != null)
      {
            ((PictureBox)GG).Image = (Image)obj;
            ((PictureBox)GG).Invalidate();
            ((PictureBox)GG).Refresh();
            using (Graphics g = ((PictureBox)GG).CreateGraphics()) {
            g.DrawString(i["amount"].ToString(), kryptonRichTextBox1.Font, 
            new SolidBrush(Color.Gold), new Point(16, 18));
      }

}

person niklon    schedule 26.01.2014    source источник


Ответы (3)


Вы изменили содержимое изображения, но PictureBox совершенно не знает об этом. Вы не переназначили его свойство Image. Вам нужно будет сказать ему, что ему нужно перерисовать изображение, отображаемое на экране. Добавьте эту строку кода:

    GG.Invalidate();
person Hans Passant    schedule 26.01.2014
comment
Я попытался добавить это ниже ((PictureBox)GG).Image = (Image)obj; строки, и текст мигает на секунду и исчезает. - person niklon; 26.01.2014
comment
Решено, ответьте в вопросе. - person niklon; 26.01.2014
comment
Хм, нет, вы все еще ошибаетесь, заставляя перерисовывать до изменения изображения. Используйте только Invalidate(), нет смысла использовать Refresh(). - person Hans Passant; 26.01.2014
comment
Но тогда это не сработало! Я проверил все возможные комбинации! - person niklon; 26.01.2014
comment
Обратите внимание, что .Refresh() будет перерисовывать немедленно, а .Invalidate() будет перерисовывать, когда это будет удобно (приложение простаивает). - person John Alexiou; 26.01.2014

Просто нарисуйте Bitmap и покажите это в PictureBox:

// A new bitmap with the same size as the PictureBox
var bitmap = new Bitmap(pictureBox.Width, pictureBox.Height);

//Get the graphics objectm which we can use to draw
var graphics = Graphics.FromImage(bitmap);

//Draw stuff
graphics.DrawString(i["amount"].ToString(), kryptonRichTextBox1.Font, 
        new SolidBrush(Color.Gold), new Point(16, 18));

//Show the bitmap with graphics image in the PictureBox
pictureBox.Image = bitmap;
person dsfgsho    schedule 26.01.2014

        Image digidashboard = new Bitmap(Properties.Resources.digidashboard);
        //using (Graphics g = ((PictureBox)pictureBoxDashboard).CreateGraphics())
        //{
        //    g.DrawString("80.00", this.Font, new SolidBrush(Color.Red), 3, 6);
        //    pictureBoxUnlock.Image = digidashboard;
        //    pictureBoxDashboard.Invalidate();
        //}
        Graphics g = Graphics.FromImage(digidashboard);
        g.DrawString("80.00", this.Font, new SolidBrush(Color.Red), 3, 6);
        pictureBoxDashboard.Image = digidashboard;

Согласно ответу Стивена Хоубена, я вставляю свою версию С#. Это работает нормально. Спасибо @StevenHouben.

person malajisi    schedule 25.02.2014