C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[2]: テーブル列をコンボボックスに表示


(過去ログ 129 を表示中)

[トピック内 12 記事 (1 - 12 表示)]  << 0 >>

■76517 / inTopicNo.1)  テーブル列をコンボボックスに表示
  
□投稿者/ 巻 (1回)-(2015/07/17(Fri) 16:31:35)

分類:[VB.NET/VB2005 以降] 

お世話になっております。
コンボボックスについてご指南願います。

■目的
  テーブル列をコンボボックスに表示させる

■現状
  通常のコンボボックスでは目的達成済み
  カスタムコントロールで作成した際に問題発生

■問題
  現状部分に記述したとおり、通常のコンボボックスでは表示させることは出来たのですが、
  カスタムコントロールでコンボボックスを作成し、同様にバインド処理をしたところ、
  コンボボックスの内容が[System.Data.DataRowView]と表示されてしまいました。

  ただ、表示されている部分(選択されている項目)については、
  [System.Data.DataRowView] ではなく項目名で表示されます。

  下記のような状態です。


  [あいうえお       ▼]
	↓
  [あいうえお       ▼]
  |System.Data.DataRowView |
  |System.Data.DataRowView |
  |System.Data.DataRowView |

  また、[System.Data.DataRowView]のどれかを選択したときは、その項目名が表示されます。

  [あいうえお       ▼]
  |System.Data.DataRowView |
  |System.Data.DataRowView |
  |System.Data.DataRowView | ← 選択
	↓
  [さしすせそ       ▼]
  |System.Data.DataRowView |
  |System.Data.DataRowView |
  |System.Data.DataRowView |


■コード
    Private Sub ComboBoxInit(ByVal SQL As String, ByVal DisplayName As String, ByVal ValueName As String)

        Me.DisplayMember = vbNullString
        Me.ValueMember = vbNullString

        '項目設定
        GetTableSQL(SQL)

	DataTable.Columns(0).ColumnName = DisplayName
	DataTable.Columns(1).ColumnName = ValueName

        Me.DataSource = DataTable

	'表示用値 設定
	Me.DisplayMember = DisplayName
        '実値 設定
	Me.ValueMember = ValueName

    End Sub

何か解決方法がございましたら、ご教授願います。
よろしくお願いします。

引用返信 編集キー/
■76518 / inTopicNo.2)  Re[1]: テーブル列をコンボボックスに表示
□投稿者/ 巻 (2回)-(2015/07/17(Fri) 16:43:25)
No76517 (巻 さん) に返信

お世話になっております。
連投失礼致します。

コンボボックスに表示するテーブルは、
NO    NAME
1    あいうえお
2    かきくけこ
3    さしすせそ

のような状態で、
DisplayMemberに、項目[NAME]
ValueMemberに、項目[NO]を設定している状態です。

SQL文は、単純に
"SELECT NO, NAME FROM T_HIRAGANA"
と記述してあります。

申し訳ありませんが、よろしくお願い致します。
引用返信 編集キー/
■76519 / inTopicNo.3)  Re[1]: テーブル列をコンボボックスに表示
□投稿者/ WebSurfer (621回)-(2015/07/17(Fri) 16:45:34)
No76517 (巻 さん) に返信

> 何か解決方法がございましたら、ご教授願います。
> よろしくお願いします。

それだけの情報ではわかりません。

Option Strict On になっていなければ On にしてみてください(明示的に設定
してなければ Off のはず)。ひょっとしたらそれで間違っている部分が見つか
るかもしれません。

Option Strict ステートメント
https://msdn.microsoft.com/ja-jp/library/zcd4xwzs.aspx

引用返信 編集キー/
■76520 / inTopicNo.4)  Re[2]: テーブル列をコンボボックスに表示
□投稿者/ 巻 (3回)-(2015/07/17(Fri) 17:08:16)
No76519 (WebSurfer さん) に返信

回答ありがとうございます。

>>何か解決方法がございましたら、ご教授願います。
>>よろしくお願いします。
> 
> それだけの情報ではわかりません。

失礼致しました。
テーブル取得の処理は以下の状態なのですが、こちらを表記しても変わりないでしょうか…。

'テーブル取得
    Public Sub GetTableSQL(ByVal SQL As String)

        _DataSet = New DataSet
        _DataTable = Nothing

        Try
            sqlCommand = New SqlCommand(SQL, SQLServer.Connection)
            sqlCommand.Transaction = SQLServer.Tran
            dataAdpt = New SqlDataAdapter(sqlCommand)
            dataAdpt.Fill(_DataSet)
            _DataTable = _DataSet.Tables(0)

        Catch Ex As Exception
            ・・・エラー処理・・・

        Finally
            If Not(sqlCommand Is Nothing) Then
                sqlCommand = Nothing
            End If
        End Try

        If _DataTable Is Nothing Then
	  Exit Function
	End If

    End Sub

> 
> Option Strict On になっていなければ On にしてみてください(明示的に設定
> してなければ Off のはず)。ひょっとしたらそれで間違っている部分が見つか
> るかもしれません。
> 
> Option Strict ステートメント
> https://msdn.microsoft.com/ja-jp/library/zcd4xwzs.aspx
> 

ご指示頂いたものを早速試してみましたが、特にエラー等は起こらず、状況も変わりませんでした。

引用返信 編集キー/
■76521 / inTopicNo.5)  Re[3]: テーブル列をコンボボックスに表示
□投稿者/ WebSurfer (622回)-(2015/07/17(Fri) 17:16:55)
No76520 (巻 さん) に返信

> テーブル取得の処理は以下の状態なのですが、こちらを表記しても変わりないでしょうか…。

そこではなくて、「カスタムコントロールでコンボボックスを作成し」というところで
質問者さんがどのようにカスタマイズしたか分からないところが問題なのです。
引用返信 編集キー/
■76522 / inTopicNo.6)  Re[3]: テーブル列をコンボボックスに表示
□投稿者/ WebSurfer (623回)-(2015/07/17(Fri) 17:19:43)
No76520 (巻 さん) に返信

ところで、最初に聞くべきでしたが、作っているのは Windows Forms
アプリですよね?

何を作っているかと開発環境は最初に書いていただけませんか。
引用返信 編集キー/
■76523 / inTopicNo.7)  Re[4]: テーブル列をコンボボックスに表示
□投稿者/ 巻 (4回)-(2015/07/17(Fri) 17:38:35)
No76522 (WebSurfer さん) に返信

回答ありがとうございます。

> そこではなくて、「カスタムコントロールでコンボボックスを作成し」というところで
> 質問者さんがどのようにカスタマイズしたか分からないところが問題なのです。

失礼致しました。
ComboBoxを継承したクラス[CstmComboBox.vb]を作成しました。

そこに、最初に投稿しました初期化処理(ComboBoxInit)を記述し、
メインフォーム(From1.vb)から呼び出しております。

> 
> ところで、最初に聞くべきでしたが、作っているのは Windows Forms 
> アプリですよね?
> 
> 何を作っているかと開発環境は最初に書いていただけませんか。

何度も申し訳ありません。

使用ソフト
Microsoft Visual Studio 2010
.net framework 4

作成物
Windows フォームアプリケーション

重ね重ね、大変失礼致しました。

引用返信 編集キー/
■76528 / inTopicNo.8)  Re[5]: テーブル列をコンボボックスに表示
□投稿者/ 魔界の仮面弁士 (413回)-(2015/07/17(Fri) 18:21:42)
No76523 (巻 さん) に返信
>> そこではなくて、「カスタムコントロールでコンボボックスを作成し」というところで
> ComboBoxを継承したクラス[CstmComboBox.vb]を作成しました。

いやいやいやいや。
その CstmComboBox 内でどのようなカスタマイズを行ったのかを、具体的に教えてくださいませ。


恐らくは、コンボボックスの表示に関わるところに手を加えていて、
そしてそこに何か過不足があるからこそ問題が起きているのでしょうけれど、
そこでどんなカスタマイズが行われていたのかがわからなければ、流石に
答えようがありません。(^_^;


…これだけでは何なので、とりあえず、こちらで勝手に
想像(という名の妄想)を膨らませてみました。


(1) 作成している「CstmComboBox クラス」は、DrawMode = DrawMode.OwnerDrawFixed な ComboBox である
 
(2) そしてそれは、OnDrawItem メソッドがオーバーライドされている
 (または DrawItem イベントを利用している)

(3) その中で、e.Graphics に DrawText メソッドで描画している
 (または、TextRenderer クラスで描画している)

(4) ところが、描画すべきテキストを取得するところで、
 データバインドのことが考慮されていなかった…と予想!

具体的にはこんな感じ?

Dim これは駄目 As String = MyBase.Items(e.Index).ToString()
Dim これならOK As String = MyBase.GetItemText(MyBase.Items(e.Index))


> メインフォーム(From1.vb)から呼び出しております。
Form1.vb ではなく?
引用返信 編集キー/
■76529 / inTopicNo.9)  Re[5]: テーブル列をコンボボックスに表示
□投稿者/ WebSurfer (624回)-(2015/07/17(Fri) 18:29:59)
No76523 (巻 さん) に返信

> ComboBoxを継承したクラス[CstmComboBox.vb]を作成しました。
> 
> そこに、最初に投稿しました初期化処理(ComboBoxInit)を記述し、
> メインフォーム(From1.vb)から呼び出しております。

やっぱり分からないです。質問に書いてない部分で問題が起こっているような
気がします。

そういう時はコードをどんどん削っていくと問題の原因が見つかる可能性が高
いです。以下のような ComboBox を表示するのに必要最低限のコードなら問題
は出ません。その差分のところに問題の原因があるはずなので、削ることによ
って差分が小さくなれば見つけやすいので。

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 DataGridViewComboBox
{
    public partial class Form3 : Form
    {
        private CustomComboBox customComboBox;

        public Form3()
        {
            InitializeComponent();
            this.customComboBox = new CustomComboBox();
            this.Controls.Add(customComboBox);
        }
    }

    public class CustomComboBox : ComboBox
    {
        public CustomComboBox()
        {            
            DataTable table = new DataTable();  
            table.Columns.Add(new DataColumn("NO", typeof(Int32)));
            table.Columns.Add(new DataColumn("NAME", typeof(string)));

            for (int i = 0; i < 3; i++)
            {
                DataRow dataRow= table.NewRow();
                dataRow["NO"] = i;
                dataRow["NAME"] = "名前-" + i.ToString();
                table.Rows.Add(dataRow);
            }

            this.DataSource = table;
            this.ValueMember = "NO";
            this.DisplayMember = "NAME";
        }
    }
}




引用返信 編集キー/
■76553 / inTopicNo.10)  Re[6]: テーブル列をコンボボックスに表示
□投稿者/ 巻 (5回)-(2015/07/22(Wed) 09:21:35)
No76528 (魔界の仮面弁士 さん) に返信

回答ありがとうございます。
返答が遅くなってしまい、申し訳ありません。

> ■No76523 (巻 さん) に返信
> (1) 作成している「CstmComboBox クラス」は、DrawMode = DrawMode.OwnerDrawFixed な ComboBox である
>  
> (2) そしてそれは、OnDrawItem メソッドがオーバーライドされている
>  (または DrawItem イベントを利用している)
> 
> (3) その中で、e.Graphics に DrawText メソッドで描画している
>  (または、TextRenderer クラスで描画している)
> 
> (4) ところが、描画すべきテキストを取得するところで、
>  データバインドのことが考慮されていなかった…と予想!

確認してみたところ、まさに上記のもの(DrowItem)が問題でした。

    Private Sub CmbBox_DrawItem(sender As Object, e As DrawItemEventArgs) Handles Me.DrawItem
        Dim cmb As ComboBox = DirectCast(sender, ComboBox)
        Dim gphc As Graphics = e.Graphics
        Dim rect As Rectangle = e.Bounds

        Dim dataTbl As DataTable = CType(Me.DataSource, DataTable)


        '背景色
        e.DrawBackground()

        If e.Index = -1 Then Exit Sub

        If cmb.Enabled Then
            'アイテムが未選択の場合、背景を白くする
            If (e.State And DrawItemState.Selected) = 0 Then
                gphc.FillRectangle(New SolidBrush(SystemColors.Window), rect)
            End If

        Else
            '無効の場合、グレーにする
            gphc.FillRectangle(New SolidBrush(SystemColors.Control), rect)
        End If

		'---変更前---
        'gphc.DrawString(cmb.Items(e.Index).ToString, e.Font, _
        '                New SolidBrush(e.ForeColor), rect)
        'e.DrawFocusRectangle()


		'---変更後---
        gphc.DrawString(dataTbl.Rows(e.Index)("NAME").ToString, e.Font, _
                        New SolidBrush(e.ForeColor), rect)
        e.DrawFocusRectangle()

    End Sub

としたところ、正常に目的の動作に辿り着く事が出来ました。

また、ComboBoxのDrawModeをNomalに変更し、DrawItemイベントをコメントアウトした場合にも
ComboBoxInitのみで目的の動作を行うことが出来ました。
ありがとうございました。

> 
>>メインフォーム(From1.vb)から呼び出しております。
> Form1.vb ではなく?

そうです、Form1.vbの間違いでした…。お恥ずかしい、すみません。

引用返信 編集キー/
■76554 / inTopicNo.11)  Re[6]: テーブル列をコンボボックスに表示
□投稿者/ 巻 (6回)-(2015/07/22(Wed) 09:25:29)
No76529 (WebSurfer さん) に返信

回答ありがとうございます。
返答が遅くなってしまい、申し訳ありません。

> ■No76523 (巻 さん) に返信
>
>>ComboBoxを継承したクラス[CstmComboBox.vb]を作成しました。
>>
>>そこに、最初に投稿しました初期化処理(ComboBoxInit)を記述し、
>>メインフォーム(From1.vb)から呼び出しております。
>
> やっぱり分からないです。質問に書いてない部分で問題が起こっているような
> 気がします。
>
> そういう時はコードをどんどん削っていくと問題の原因が見つかる可能性が高
> いです。以下のような ComboBox を表示するのに必要最低限のコードなら問題
> は出ません。その差分のところに問題の原因があるはずなので、削ることによ
> って差分が小さくなれば見つけやすいので。

自分の勉強不足と理解力の低さのため、お手数をおかけ致しまして本当に申し訳ありません。
次回からは、ご指南頂いたことを実践していきます。

本当にありがとうございました。
引用返信 編集キー/
■76555 / inTopicNo.12)  Re[2]: テーブル列をコンボボックスに表示
□投稿者/ 巻 (7回)-(2015/07/22(Wed) 09:26:10)
No76518 (巻 さん) に返信
> ■No76517 (巻 さん) に返信

クローズします。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -