C#の派生クラスで描画処理を行う方法

このQ&Aのポイント
  • C#でGUIを作成している際に、基本クラスで描画処理を行うことはできましたが、派生クラスで同じ処理を行っても表示されません。
  • 基本クラスのメソッドを派生クラスで呼び出しても、描画が反映されない問題が発生しています。
  • この問題の解決方法についてご教授いただけると幸いです。
回答を見る
  • ベストアンサー

C#で派生クラスから描画処理を行う

C#を勉強しているのですが、GUIを作り初めて描画処理で分からない所があり、質問させて頂きます。 基本クラスの方で「Hello, world!」という文字列をDrawStringで表示させる事は出来たのですが、それを基本クラスを継承した派生クラスのメソッドで行うと何も表示されないんです。 以下が試したコードです。 //基本クラスSample1 using System; using System.Drawing; using System.Windows.Forms; public class Sample1 : Form {   protected Bitmap image; protected Graphics g; protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); Sample2 s = new Sample2(); s.helloworld(); e.Graphics.DrawImage(image, 0, 0); } public Sample1() { SetStyle(ControlStyles.DoubleBuffer | ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true); image = new Bitmap(600, 400); g = Graphics.FromImage(image); } static void Main() { Form form = new Sample1(); form.Text = "sample"; form.ClientSize = new Size(600, 400); form.BackColor = Color.FromArgb(0xff, 0xff, 0xff); Application.Run(form); } } //派生クラスSample2 using System; using System.Drawing; using System.Windows.Forms; public class Sample2 : Sample1 { Brush brush = new SolidBrush(Color.Black); public void helloworld() { g.DrawString("Hello, world!", this.Font, brush, 10, 10); } } なぜ表示されないのか分かる方いらしたら、ご教授願えないでしょうか。是非お願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.1

DrawImageで描画しようとしているのが 何も描画されていない Sample1.Imageだからだと思います Sample2 s = new Sample2(); s.helloworld(); で描画されてるのは s.image であり呼び出し元のForm.imageに描画されるわけではありません OnPaintの中を base.OnPaint(e); Sample2 s = new Sample2(); s.helloworld(); // this.imageでは無く s.imageを描画 e.Graphics.DrawImage(s.image, 0, 0); といった具合に変更しましょう

lottimismo
質問者

お礼

回答有難う御座います。 言われた通り書き直しまして、見事表示させる事ができました。本当に有難う御座いました。

関連するQ&A

  • なぜprotected overrideなのか

    C#でわからないことが2,3あるのですが、このmsndのサンプルで public class FirstControl : Control{ public FirstControl() {} protected override void OnPaint(PaintEventArgs e) { // Call the OnPaint method of the base class. base.OnPaint(e); // Call methods of the System.Drawing.Graphics object. e.Graphics.DrawString(Text, Font, new SolidBrush(ForeColor), ClientRectangle); } } これのprotected override void OnPaint(PaintEventArgs e){} の部分なのですが、なぜprotected overrinde修飾子なのでしょう 何をオーバーライドしてるのですか?他のサンプルにも構文のように出てくるのですが。 あとOnPaintはメソッドのようですがイベントを発生させるにはデリゲートではないのでしょうか あとPaintEventArgsはクラスということですがnewはいらないのでしょうか。staticがどこかにあるのでしょうか よろしくお願いします。

  • Visual C# 2008 Express Editionで実行するとDOS窓が出る

    私はC#でフォームプログラミングを勉強しようと思い、「Visual C# 2008 Express Edition」をダウンロードして、取り合えずウィンドウを作るだけの簡単なプログラムを実行してみたのですが、ウィンドウと同時に黒い窓(DOS窓というのでしょうか)が現れてしまいます。 作成したアプリケーションデータを実行しても、やはり黒い画面が出てしまい困っています。 本に掲載されていたコードをウィンドウタイトルを変えて、そのままビルドしただけですし、本に付いてきたCD-ROMの中の同じサンプルプログラムのアプリケーションデータを実行しても、黒い画面は現れません。何か方法に誤りがあるのでしょうか、分かる方がいたら教えて頂きたいのですが、下がコードです。 using System; using System.Drawing; using System.Windows.Forms; public class Test : Form { protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); } static void Main() { Form form = new Test(); form.Text = "ウィンドウタイトル"; form.ClientSize = new Size(600, 400); form.BackColor = Color.FromArgb(0xff, 0xff, 0xff); Application.Run(form); } } 参照設定には、 System System.Drawing System.Windows.Forms を含めています。

  • C#のGraphicsクラスについて(GDI+)

    以下のようにgraphicsクラスをつかった画像の描画をおこないました。 Graphics gr = Graphics.FromImage(mapObj); というふうにからのリソースからGraphicsオブジェクトをつくる方法です。 using System; using System.IO; using System.Windows.Forms; using System.Drawing; using System.Web; using System.Net; using System.Text; using System.Threading; using System.ComponentModel; public class MainClass{ public static void Main(string [] args){ NewForm formObj = new NewForm(); formObj.RenderMethod(); Application .Run(formObj); } } public class NewForm : Form{ public NewForm(){ this.Width = 500; this.Height = 500; } public void RenderMethod(){ Bitmap mapObj = new Bitmap(500,500); Graphics gr = Graphics.FromImage(mapObj); Image imageObj = Image.FromFile("C:\\test.jpg"); gr .DrawImage(imageObj, 0,0,150,150); this.BackgroundImage = mapObj; } } このほかに、フォームコントロールの thisl.CreateGraphics()という メソッドを使っても画像を描画できるとききました。 あるサンプルをみると public class NewForm : Form{ public NewForm(){ this.Width = 500; this.Height = 500; } public void RenderMethod(){ Graphics gr = this.CreateGraphics(); Image imageObj = Image.FromFile("C:\\test.jpg"); gr .DrawImage(imageObj, 0,0,150,150); } } とこのようにthis.CreateGraphics()をつかっていましたが 実際にはこれが描画されないのです。 Graphics gr = Graphics.FromImage(mapObj); というGraphicsクラスの静的メソッドを使う方法ではなく コントロールのCreateGraphicsメソッドをつかって描画するにはどうしたらよいのですか? 識者のかた、ご教授ください。

  • Graphicsプロパティ

    例えば using System; using System.Drawing; using System.Windows.Forms; class SeparateMain { public static void Main() { Application.Run(new AnotherHelloWorld()); } } class AnotherHelloWorld : Form { public AnotherHelloWorld() { Text = "Another Hello World"; BackColor = Color.White; } protected override void OnPaint(PaintEventArgs pea) { Graphics grfx = pea.Graphics; grfx.DrawString("Hello, windows Forms!", Font, Brushes.Black, 0, 0); } } の中の Graphics grfx = pea.Graphics; という部分なのですが、この部分はなぜ必要で、何をしてるのでしょう。 GDI+というのでしょうか System.Drawing.Graphicsというクラスのインスタンス、grfxを定義して、 PaintEventArgsのインスタンスpeaのGraphicsプロパティを代入 この処理が必要な理由がわかりません。お願いします。

  • C#での画像ファイルをドラッグアンドドロップで描画

    C#で画像ファイルをドラッグアンドドロップで描画させるプログラムを作りたいのですが、うまくできません。 ドラッグしたファイル名を読み取る部分までは動作確認できています。このファイル名の画像ファイルをForm1に描画させる部分でエラーになってしまいます。 どのように修正したらよいのかわからないのでお助けください。 ----- using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; namespace Drag {   public partial class Form1 : Form   {     public Form1()     {       InitializeComponent();     }     private void Form1_DragEnter(object sender, DragEventArgs e)     {       e.Effect = DragDropEffects.All;     }     private void Form1_DragDrop(object sender, DragEventArgs e)     {       Graphics g = e.Graphics;   // <------ エラーになる。       if (e.Data.GetDataPresent(DataFormats.FileDrop))       {         foreach (string fileName             in (string[])e.Data.GetData(DataFormats.FileDrop))         {           g.DrawImage(new Bitmap(fileName, new PointF(10F, 50F)));           // Console.WriteLine(fileName); // 動作確認         }       }     }   } }

  • なぜForm型にキャストするのでしょう?

    using System; using System.Drawing; using System.Windows.Forms; class PaintHello { public static void Main() { Form form = new Form(); form.Text = "Paint Hello"; form.BackColor = Color.White; form.Paint += new PaintEventHandler(MyPaintHandler); Application.Run(form); } static void MyPaintHandler(object objSender,PaintEventArgs pea) { Form form = (Form)objSender;//←この部分が分かりません。 Graphics grfx = pea.Graphics; grfx.DrawString("Hello,world!", form.Font, Brushes.Black, 0, 0); } } C#の勉強をしているのですが、イベントを発生させるためにデリゲートに自分で作ったメソッドを 引数として送るというのは理解できるのですが、 このMyPaintHandlerのobject objSender という部分が、書籍の説明だと「objSenderはForm型のオブジェクトなのでキャストはうまくいく」 と書かれています。 object型というのを調べるとSystem名前空間にObjectというクラスがあるのですが、これはすべてのクラスのルートであり、、、とMSDNに書かれていて、なぜForm型と言えるのかわかりません。 そもそもこのキャストはなぜ必要なのでしょう。お願いします。

  • C# フォームプログラミングで

    public partial class Form2 : Form { public Form2() { InitializeComponent(); } private void Form2_Load(object sender, EventArgs e) { //Graphics grfx = CreateGraphics(); } private void Form2_Paint(object sender, PaintEventArgs e) { Form2 form2; form2.Paint += new PaintEventHandler(PaintHandler1); } static void PaintHandler1(object objSender,PaintEventArgs e) { Graphics grfx = e.Graphics; grfx.DrawString("test",Font font,Brushes.Black,0,0);//←ここでエラー } } このように書くと「引数を2個指定できる、メソッド DrawString のオーバーロードはありません」 というエラーがでてフォームに文字を表示できません 最初に「空のプロジェクト」で作れば普通にDrawStringで文字を表示できるのですが 「Windowsフォーム」を選んでからだと表示できないのはなぜでしょうか? 何がいけないのでしょう。

  • C#のGraphicsクラスについてです。

    C#のGraphicsクラスを用いて画像をフェードインで表示させよとしています。 まず以下のコードをごらんください。 ただ、フェードインで画像は表示されるものの、フォームの操作が一切できなくなってしまいます。 そのためマルチスレッドにしようとしたのですが using System; using System.IO; using System.Windows.Forms; using System.Drawing; using System.Web; using System.Net; using System.Text; using System.Threading; using System.Drawing.Drawing2D; using System.Drawing.Imaging; using System.Diagnostics; public class MainClass{ public static void Main(string [] args){ NewForm formObj = new NewForm(); Application .Run(formObj); } } public class NewForm : Form { //インスタンス変数の宣言 public Graphics g ; public Bitmap mapObj ; public Image imageObj; public ImageAttributes ia; public ColorMatrix cm; public Thread th ; public ParameterizedThreadStart ts; public PaintEventArgs e; public Rectangle rec; public int flag = 0; public delegate void TestDelegate(); public TestDelegate deleObj; public NewForm(){ Button buttonObj = new Button(); buttonObj.Width=100; buttonObj.Height = 30; //フェードさせるためのイベント発行用ボタンの設置 buttonObj.Click += new EventHandler(this.SetMethod); this.Controls.Add(buttonObj); } public void SetMethod(object sender , EventArgs e){ this.Paint += new PaintEventHandler(this.ThreadMethod); //フォームコントロールの再描画を促す this.Invalidate(); } public void ThreadMethod(object sender ,PaintEventArgs eventObj){ this.ts = new ParameterizedThreadStart(this.ThreadRenderMethod); this.th = new Thread(this.ts); this.th.Start(eventObj); MessageBox.Show("ThreadMethod実行後"); MessageBox.Show(InvokeRequired.ToString()); this.th.Join(); } public void ThreadRenderMethod(object paintObj){ MessageBox.Show(InvokeRequired.ToString()); this.deleObj =delegate(){ //無現ループしてしまうので、再描画イベント後イベントハンドラーを削除 this.Paint -= new PaintEventHandler(this.ThreadMethod); PaintEventArgs e = (PaintEventArgs)paintObj; try{ Console.WriteLine("paint メソッド発生"); this. g = e.Graphics; this.mapObj = new Bitmap(this.Width,this.Height); this.imageObj = Image.FromFile("C:\\c#\\test.jpg"); //this.g = Graphics.FromImage(this.mapObj); this.cm = new ColorMatrix(); this.cm.Matrix00 = 1; this.cm.Matrix11 = 1; this.cm.Matrix22 = 1; this.cm.Matrix33 = 0.0F; this.cm.Matrix44 = 1; this.ia = new ImageAttributes(); this.ia.SetColorMatrix(this.cm); this.rec = new Rectangle(0, 0, this.Width, this.Height); this.g.DrawImage(this.imageObj,rec,0,0,this.imageObj.Width,imageObj.Height,GraphicsUnit.Pixel,this.ia); this.BackgroundImage = mapObj; for(double i = 0.0; i <= 1.0; i = i + 0.001){ this.cm.Matrix33 = (float) i; this.ia.SetColorMatrix(this.cm); this.g.DrawImage(this.imageObj,rec,0,0,this.imageObj.Width,imageObj.Height,GraphicsUnit.Pixel,this.ia); this.BackgroundImage = this.mapObj; Thread.Sleep(100); } //this.imageObj.Dispose(); //this.g.Dispose(); }catch(Exception ex){ Console.WriteLine(ex.ToString()); } Console.WriteLine("paint end"); }; this.deleObj(); //this.Invoke(this.deleObj); this.BackgroundImage = Image.FromFile("C:\\c#\\test.jpg"); } } 上記コードでも、フェードは動作するものの、やはりフォームの操作ができなくなります。 どう対処したらよいでしょうか? 識者の方、よろしくご教授ください お願いいたします

  • VC# 追加フォーム生成時、フォームに描画できない

    前略 ・VC#(.NET 2008)のプログラムでおしえてください。 ・メインのWindowsフォームからボタンクリックで 追加したサブWindowsフォーム上のピクチャーボックス上に何も操作なしでに描画したいのですができません。CreateGraphics()でオブジェクトを生成して描画しています。どのようにしたらよいのかおしえてください。フォームのイベントとして、Paint,Load,shown,Activated等いろいろやってもだめでした。  尚、サブフォームにボタンをもうけ このメソッドの中に描画コマンドを書き、ボタンを操作すると描画できます。下記は円を描こうとしていますが、shapeコンポーネントでは描けな複雑な描画をしたいと思っています。 ・以下に 下記の動作となるソースコードを記載します。 (1)起動するとメインフォームForm1のpictureBox1に 赤い円が描かれる (2)ボタンbutton1をクリックするとForm2が表示される。  Form2上のラベルlabel1とlabel2の文字色は青色に変わっています。  しかし、円は何故か描かれていません (3)Form2上のボタンをクリックすると赤い円がForm2上に描かれます。  どこをどのように直せば追加のサブフォームForm2が表示された時に Form2上のpictureBox1に円が描がかれているのでしょうか。以上、よろしくお願いします //----------------------------------------------------------- //メインフォーム using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace temp2 { public partial class Form1 : Form { public Form1(){ InitializeComponent(); } private void button1_Click(object sender, EventArgs e){ Form2 form2 = new Form2(); form2.ShowDialog(); } private void Form1_Paint(object sender, PaintEventArgs e){ Graphics g = pictureBox1.CreateGraphics(); g.DrawEllipse(Pens.Red, 0, 0, 200, 200); } } } //サブフォーム using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace temp2 { public partial class Form2 : Form { public Form2(){ InitializeComponent(); } private void pictureBox1_Paint(object sender, PaintEventArgs e){ label1.ForeColor = Color.Blue; Graphics g1 = pictureBox1.CreateGraphics(); g1.DrawEllipse(Pens.Blue, 0, 0, 50, 50); label2.ForeColor = Color.Blue; } private void button1_Click(object sender, EventArgs e){ Graphics g2 = pictureBox1.CreateGraphics(); g2.DrawEllipse(Pens.Blue, 0, 0, 50, 50); } private void Form2_Paint(object sender, PaintEventArgs e){ } private void Form2_Load(object sender, EventArgs e){ } private void Form2_Shown(object sender, EventArgs e){ } } } 以上

  • 別クラスからTextFieldなどを加える方法

    メインのクラスとは別のクラスでボタンなどを表示させたいのですが、方法がわかりません。 一応 import java.awt.*; import java.awt.event.*; class Test extends Frame{ private Image offImage; //仮想画面 private Graphics gv; // 仮想画面Graphicsオブジェクト private SubClass SC; //サブクラス public Test(){ setTitle("Test"); setSize(400,300); setVisible(true); //仮想画面の生成 offImage = createImage(400,300); gv = offImage.getGraphics(); //閉じる addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) {System.exit(0);}}); //サブクラス生成 SC = new SubClass(this); myDraw(); } public static void main(String args[]){ Frame f = new Test(); } public void myDraw(){ gv.drawString("仮想画面を使って表示しています。",100,100); } public void paint(Graphics g){ //仮想画面を表示 g.drawImage(offImage,0,0,this); } public void update(Graphics g){} } class SubClass{ Test T; public SubClass(Test t){ T = t; T.add(new TextField(10)); } } こんな感じでやろうとしてみたのですが、できません。 どうすればいいか教えてください!!お願いします。。。

専門家に質問してみよう