質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Q&A

解決済

2回答

13168閲覧

C#のcomboboxの要素による条件分岐

退会済みユーザー

退会済みユーザー

総合スコア0

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

0グッド

0クリップ

投稿2017/04/21 01:34

現在C#を用いて、
マウスのドラッグで矩形を描くプログラムを作成しています。
描く矩形の形は、comboboxによって変えようと思います。

ObjSelectFrm.cs namespace ObjectSelectTool { public partial class ObjSelectFrm : Form { #region インターナルクラス /// <summary> /// 効果オブジェクトをコードのセットクラス /// </summary> internal class BaseImage { /// <summary> /// Image ファイル名称 /// </summary> public string Fname { set; get; } } #endregion #region プロパティ /// <summary> /// ユーザイベント /// </summary> public Event.ObjsEventCalled EventCalled { set { this.eventcalled = value; } get { return this.eventcalled; } } #endregion #region コンストラクター /// <summary> /// コンストラクター /// </summary> public ObjSelectFrm() { InitializeComponent(); this.cntlmouse = new SelectObjs.ControlMouse(); this.attrigrp = new SelectObjs.AttributeGroup(); this.eventcalled = new Event.ObjsEventCalled(); } #endregion #region プライベート変数 //ベース画像 private const string BASE_IMAGE = "\\fruit.jpg"; //マウス制御オブジェクト private SelectObjs.ControlMouse cntlmouse = null; //オブジェクトリスト管理 private SelectObjs.AttributeGroup attrigrp =null; //グラフィックス管理 private ToolGraphics.ContorlGraphics cntlgra = null; //ユーザイベント private Event.ObjsEventCalled eventcalled = null; #endregion #region フォームロード /// <summary> /// フォームロードイベント /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void ObjSelectFrm_Load(object sender, EventArgs e) { //コンボボックスに要素を追加 comboBox1.Items.Add("四角形"); comboBox1.Items.Add("楕円形"); //コンボボックスの初期値設定 comboBox1.SelectedIndex = 0; } private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) { } } }

このようなコンボボックスがあって、
外部のクラスでDrewしたいのですが、
その時に
if(){
DrawRectangle
}else{
DrawEllipse
}
としたいとき、ifのかっこの中の条件はどのようにしてあげればいいか
お教えいただきたいです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

if文で何を条件にするか…?
とりあえず上記の条件であればシンプルに考えれば以下ですね。

if (comboBox1.SelectedIndex == 0) { DrawRectangle(); } else { DrawEllipse(); }

でも図形の種類が増える度にif文を追加していくのは微妙ですよね。
並列的な処理分岐にはswitch文を使います。

switch (comboBox1.SelectedIndex) { case 0: DrawRectangle(); break; case 1: DrawEllipse(); break; }

よりよい形もありますが、そちらはまだ早いのでリンクだけにしておきます。

デザインパターンとOpen-Closed Principle

上記サイトは直接的にこの問題について回答したものではありませんので要約すると、if文やswitch文を使わずに図形描画に対応することで、描画する図形を増やしたい場合に、描画処理を変更しなくてもよくなります。ブックマークされておくと良いでしょう。


次のステップとしては、コンボボックスと描画処理を分けましょう。

・図形を指定する設定値を作る
・コンボボックスから描く図形の種類を得る
・描画処理に利用する

図形を指定する設定値を作る

今回はもっとも単純な方法として、定数を使いましょう。

C#

1enum Shape 2{ 3 None, 4 Rectangle, 5 Ellipse 6}

コンボボックスから描く図形の種類を得る

以下はWindowsFormを使う上での最良の形ではありません。
しかし、とりあえずこの関数を呼べば設定値を得る、という目的は達成されます。
よりよい形が何かを模索していくと良いでしょう。
重要なのは、この関数を呼べば何を描こうとしているのか分かるようになっているということです。

Shape GetSelectedShape() { switch(comboBox1.SelectedIndex) { case 0: return Shape.Rectangle; case 1: return Shape.Ellipse; } return Shape.None; } // こういう値は通常C#ではプロパティにします。 Shape SelectedShape { get { switch(comboBox1.SelectedIndex) { case 0: return Shape.Rectangle; case 1: return Shape.Ellipse; } return Shape.None; } }

描画処理に利用する
設定値を取得できるようになったら、comboBox1.SelectedIndexを置き換えましょう。
これで、インデックス値と描画の選択を分離することができます。

switch (GetSelectedShape()) { case Shape.Rectangle: DrawRectangle(); break; case Shape.Ellipse: DrawEllipse(); break; }

投稿2017/04/21 02:09

haru666

総合スコア1591

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/04/21 02:34

回答ありがとうございます。はじめ、自分も一番上に書いてくださった方法でやろうとしましたが、 このコンテキストにcomboBox1という名前がが存在しません。というエラーが出てしまいます。書洩らして申し訳ございません。こちらの解決方法をお教えいただけないでしょうかよろしくお願いします。
ku__ra__ge

2017/04/21 07:53

ObjSelectFrmとは別のフォームからObjSelectFrmのcomboBox1を見たいのであればModifiersプロパティを変更する必要があります。デザイン時にcomboBox1のプロパティでModifiersをinternalに設定して、利用側フォームので「《ObjSelectFrmのインスタンス》.comboBox1」のようなコードでアクセスしてみてください。
haru666

2017/04/24 01:38

if文まったく関係ないですね… 外部クラスのインスタンス化、呼び出しはどのようになっているでしょうか。 それによって最適な方法は変わるので即答できません。 また、現在のレベルなら外部クラスを止めるのも手です。 何故外部クラスにするのかさえ判断する力がまだなさそうだからです。
guest

0

ベストアンサー

DisplayMember, ValueMember を使ったこんな方法もありますので、参考になりましたらどうぞ。

C#

1using System; 2using System.Drawing; 3using System.Windows.Forms; 4 5namespace WindowsFormsApp1 6{ 7 public partial class Form1 : Form 8 { 9 public Form1() 10 { 11 InitializeComponent(); 12 } 13 14 private void Form1_Load(object sender, EventArgs e) 15 { 16 comboBox1.DisplayMember = "Text"; 17 comboBox1.ValueMember = "Action"; 18 comboBox1.DataSource = new[] 19 { 20 new 21 { 22 Text = "四角形", 23 Action = new Action(() => 24 { 25 var random = new Random(); 26 CreateGraphics() 27 .DrawRectangle( 28 new Pen(new SolidBrush(Color.Red)), 29 new Rectangle( 30 random.Next(ClientSize.Width / 2), 31 random.Next(ClientSize.Height / 2), 32 random.Next(ClientSize.Width / 2), 33 random.Next(ClientSize.Height / 2) 34 ) 35 ); 36 }) 37 }, 38 new 39 { 40 Text = "楕円形", 41 Action = new Action(() => 42 { 43 var random = new Random(); 44 CreateGraphics() 45 .DrawEllipse( 46 new Pen(new SolidBrush(Color.Green)), 47 new Rectangle( 48 random.Next(ClientSize.Width / 2), 49 random.Next(ClientSize.Height / 2), 50 random.Next(ClientSize.Width / 2), 51 random.Next(ClientSize.Height / 2) 52 ) 53 ); 54 }) 55 } 56 }; 57 } 58 59 private void comboBox1_SelectedValueChanged(object sender, EventArgs e) 60 { 61 var comboBox = sender as ComboBox; 62 if (comboBox == null) return; 63 var action = comboBox.SelectedValue as Action; 64 if (action == null) return; 65 action(); 66 } 67 } 68}

投稿2017/04/27 15:04

Zuishin

総合スコア28660

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問