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

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

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

.NET Coreは、マネージソフトウェアフレームワークでオープンソースで実装されています。クロスプラットフォームを前提に考えられており、Windows/Mac/Linuxで動くアプリケーションを作成することが可能です。

C#

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

Visual Studio

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

Q&A

解決済

1回答

359閲覧

DrawItemを設定したコンボボックスを開こうとすると3度クリックしないと開かない

asuka77728

総合スコア4

.NET Core

.NET Coreは、マネージソフトウェアフレームワークでオープンソースで実装されています。クロスプラットフォームを前提に考えられており、Windows/Mac/Linuxで動くアプリケーションを作成することが可能です。

C#

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

Visual Studio

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

1グッド

0クリップ

投稿2024/02/01 11:00

編集2024/02/01 11:01

実現したいこと

コンボボックスのソースに複数列を表示したく、DrawItemイベント時に複数列を描画する処理を入れました。すると、コンボボックスを3回クリックすると、ドロップダウンが表示されます。描画自体は正しくなされています。コンボボックスを1回のクリックでドロップダウンしたい

発生している問題・分からないこと

一度ドロップダウンすると、そのフォームが閉じない限りは、1クリックでドロップダウン表示されるようになります。
プロパティは設定しています
DropDownStyle: DropDown
DrawMode: OwnerDrawFixed

該当のソースコード

C#

1 private void 分類コード_DrawItem(object sender, DrawItemEventArgs e) 2 { 3 OriginalClass.SetComboBoxAppearance((ComboBox)sender, e, new int[] { 50, 500 }, new string[] { "Display", "Display2" }); 4 分類コード.Invalidate(); 5 // 分類コード.DroppedDown = true; 6 } 7 8drawItemイベントです
public static void SetComboBoxAppearance(ComboBox cb, DrawItemEventArgs e, int[] fieldWidth, String[] fieldName) { DataTable dt = (DataTable)cb.DataSource; Pen p = new Pen(Color.Gray); Brush b = new SolidBrush(e.ForeColor); //背景の描画 e.DrawBackground(); int width = 0; for (int i = 0; i < fieldName.Length; i++) { //テキストの描画 e.Graphics.DrawString(Convert.ToString(dt.Rows[e.Index][fieldName[i]]), e.Font, b, width, e.Bounds.Y); //縦線の描画 e.Graphics.DrawLine(p, width + fieldWidth[i], e.Bounds.Top, width + fieldWidth[i], e.Bounds.Bottom); width = width + fieldWidth[i]; } cb.DropDownWidth = width; //選択状態の描画 if (Convert.ToBoolean(e.State & DrawItemState.Selected)) ControlPaint.DrawFocusRectangle(e.Graphics, e.Bounds); } 描画用の関数です 
public void SetComboBox(ComboBoxCell comboBox, string sqlQuery) { try { Connect(); using (SqlCommand command = new SqlCommand(sqlQuery, cn)) { using (SqlDataAdapter adapter = new SqlDataAdapter(command)) { DataTable dataTable = new DataTable(); adapter.Fill(dataTable); comboBox.DataSource = dataTable; comboBox.DisplayMember = "Display"; comboBox.ValueMember = "Value"; comboBox.DataSource = dataTable; } } } catch (Exception ex) { MessageBox.Show("データの読み込み中にエラーが発生しました: " + ex.Message, "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error); } } コンボボックスのセット用関数です。

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

drawItemイベントに、無理やりドロップダウンを入れると、一瞬ドロップダウンが開いてすぐに閉じます。
データソースを1レコードにしてみても同じ現象が起こります。
表示カラムを1列にしても同じ現象が起こります。

補足

C# .net6 winforms 
visual studio 2022 Version 17.5.4
他必要な情報はございますか

TN8001👍を押しています

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

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

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

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

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

TN8001

2024/02/01 15:09

参考コードがある場合は質問に明記してください。 [【C#】コンボボックスに複数列を表示する – カプログ](https://couplog.hana87.club/578.html) 「ComboBoxCell」とはなんでしょうか? これですか? [DataGridViewComboBoxCell クラス (System.Windows.Forms) | Microsoft Learn](https://learn.microsoft.com/ja-jp/dotnet/api/system.windows.forms.datagridviewcomboboxcell) それともサードパーティのコントロールでしょうか? > DrawItemを設定したコンボボックスを開こうとすると3度クリックしないと開かない 「DrawItemを設定しなければ」1クリックで開くという意味ですか? もしかしてDataGridViewComboBoxColumnでの話ですか? [DataGridViewのコンボボックスのドロップダウンリストが一回のクリックで表示されるようにする - .NET Tips (VB.NET,C#...)](https://dobon.net/vb/dotnet/datagridview/oneclickdropdown.html) [datagridviewcomboboxcolumn クリック - Google 検索](https://www.google.co.jp/search?q=datagridviewcomboboxcolumn+%E3%82%AF%E3%83%AA%E3%83%83%E3%82%AF)
asuka77728

2024/02/02 01:51

ご回答ありがとうございます >参考コードがある場合は質問に明記してください。 失礼しました。作法を存じ上げていませんでした >「ComboBoxCell」とはなんでしょうか? すみません、「ComboBoxCell」はサードパーティ製のコンボボックスです。 通常のコンボボックスもありまして、以下の様に、 public void SetComboBox(ComboBox comboBox, string sqlQuery) 全く同様の処理で、引数だけ変更してオーバーライドしているメソッドもあります。そちらを貼り付けるべきでした。間違えてconboboxcellを受け取る処理を貼り付けていますが、今回の質問で実行されているのは通常のComboBox の方です。すみませんでした。 >「DrawItemを設定しなければ」1クリックで開くという意味ですか? その場合は、1クリックで開きます >もしかしてDataGridViewComboBoxColumnでの話ですか? 通常のコンボボックスになります ※必要かどうかわからなかったので記載しませんでしたが、フォームのLoadイベントで下記を設定しています。 OriginalClass ofn = new OriginalClass(); ofn.SetComboBox(分類コード, "SELECT XXXX as Display, OOOO as Display2 ,XXXX as Value FROM テーブル名 " ; 分類コード.DrawMode = DrawMode.OwnerDrawFixed; 他、何か必要な情報等ございますでしょうか?
guest

回答1

0

ベストアンサー

cb.DropDownWidth = width;

これが悪さをしているようです(変更すると見えなくなっちゃう?特に突っ込んで調べる気はないです^^;

クリック1回目:開いてはいるが見えない?
クリック2回目:閉じた
クリック3回目以降:普通に開く

DropDownWidthを途中で変えることはないでしょうから、事前に設定しておけばいいでしょう。

cs

1using System.Data; 2 3namespace Q3uekpjbil0sxwq; 4 5public partial class Form1 : Form 6{ 7 public Form1() 8 { 9 InitializeComponent(); 10 11 var comboBox1 = new ComboBox 12 { 13 FormattingEnabled = true, 14 Location = new Point(12, 12), 15 Size = new Size(355, 32), 16 Parent = this, 17 }; 18 SetComboBox(comboBox1, "dummy"); 19 SetMultiColumn(comboBox1, ("Display", 50), ("Display2", 500)); 20 } 21 22 private void SetComboBox(ComboBox comboBox, string sqlQuery) 23 { 24 var dataTable = new DataTable(); 25 dataTable.Columns.Add("Display"); 26 dataTable.Columns.Add("Display2"); 27 dataTable.Columns.Add("Value"); 28 29 dataTable.Rows.Add("1", "Display1", 100); 30 dataTable.Rows.Add("2", "Display2", 200); 31 dataTable.Rows.Add("3", "Display3", 300); 32 33 comboBox.DataSource = dataTable; 34 comboBox.DisplayMember = "Display"; 35 comboBox.ValueMember = "Value"; 36 } 37 38 private void SetMultiColumn(ComboBox comboBox, params (string Name, int Width)[] columns) 39 { 40 comboBox.DrawMode = DrawMode.OwnerDrawFixed; 41 42 // 事前に設定 43 comboBox.DropDownWidth = columns.Sum(x => x.Width); 44 45 comboBox.DrawItem += (sender, e) => 46 { 47 if (sender is ComboBox { DataSource: DataTable dt }) 48 { 49 e.DrawBackground(); 50 51 using var p = new Pen(Color.Gray); 52 using var b = new SolidBrush(e.ForeColor); 53 54 var width = 0; 55 foreach (var column in columns) 56 { 57 e.Graphics.DrawString(dt.Rows[e.Index][column.Name].ToString(), e.Font, b, width, e.Bounds.Y); 58 width += column.Width; 59 e.Graphics.DrawLine(p, width, e.Bounds.Top, width, e.Bounds.Bottom); 60 } 61 62 // 変更すると見えなくなっちゃう? 63 //comboBox.DropDownWidth = width; 64 65 e.DrawFocusRectangle(); 66 } 67 }; 68 } 69}

投稿2024/02/02 08:50

TN8001

総合スコア9326

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

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

asuka77728

2024/02/02 10:51

回答ありがとうございます。 素晴らしいです、解決しました!!! ただ、DrawItemの処理を80か所程度登録しているため、すべてを例の様に変更するのは手間のため、各フォームのコンストラクタに コンボボックス名.DropDownWidth = 550; の様な感じで登録していくようにしました。それもあまり手間は変わらない気もしますが。 お手数おかけしまして、お手数おかけしまして、誠にありがとうございました! ベストアンサーに選ばせていただきました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問