none
WPFのComboBoxにsqlの結果をバインド RRS feed

  • 質問

  • C#2013を用いてデータベースシステムのWPFアプリを作成しています。

    ComboBoxにSQL結果を入力したいため下記のようなコードを実行しています。

    返ってきた結果をレコードの最初から最後まで順番にComboBoxにAddしています。

    while (reader.Read())
    {
    this.comboBox.Items.Add((String)reader.GetValue(0) );

    }

    しかし、この方法ではAccessと比較しても時間がかかってしまいます。

    SQLの結果をcomboBoxのitemsSourceにバインドすれば速度の向上が期待できると思い、調べたのですが、

    具体的な方法がわかりません。

    お分かりになられる方がいらっしゃいましたらご教授よろしくお願い致します。

    2015年3月4日 11:42

回答

  • ComboBoxとデータベースとのバインドは DataTable を使った方がいいでしょう。

    補足しておきますね。ComboBoxとDataTableは直接バインドできません。なので、ひらぽんさんのブログを紹介しておきます。

    Q029. ComboBox に Datasource は指定できないのですか?
    http://d.hatena.ne.jp/hilapon/20101128/1295832349

    しかしコードビハインドで直接 ComboBox とバインドさせる方法は WPF で開発する利点を大きく損ないます。データベースからドメインモデルのコレクションを生成し、ビューモデルを介してバインドさせる方法をお勧めします。具体的な実装は Tak1wa さんが提示されてるので参考になるかと思います。

    こちらも補足させて下さい。
    今は質問者さんはMVVMで開発されていないようですが、WPFではMVVMで開発することが主流になっています。MVVMはデザインパターンの一つですので、どうしてもMVVMでなければならないということはありませんが、WPFのバインド機能をうまく引き出せるパターンだと思いますので、いずれMVVMで開発されることをおすすめします。
    さて、MVVMで開発されると、ObservableCollectionが良く出てきます。これはコレクションの変更をバインド先に伝える機能を持っているからです。もし、その必要が無いのであれば、ObservableCollectionを使う必要はありません。Listでも十分です。例えばデータベースからselectしてきたレコードの参照しかしないような場合です。その辺りをご判断下さい。


    ★良い回答には回答済みマークを付けよう! MVP - .NET  http://d.hatena.ne.jp/trapemiya/

    • 回答としてマーク protecyamyam 2015年3月10日 12:48
    2015年3月5日 1:14
    モデレータ
  • ComboBoxとデータベースとのバインドは DataTable を使った方がいいでしょう。
    しかしコードビハインドで直接 ComboBox とバインドさせる方法は WPF で開発する利点を大きく損ないます。データベースからドメインモデルのコレクションを生成し、ビューモデルを介してバインドさせる方法をお勧めします。具体的な実装は Tak1wa さんが提示されてるので参考になるかと思います。

    「不適切な発言」の濫用はフォーラムの運営を妨げる行為です。ご遠慮ください https://social.msdn.microsoft.com/Forums/ja-JP/0f7b0966-0141-4c1b-b7b9-aed65abf60b6?forum=announceja

    • 回答としてマーク protecyamyam 2015年3月10日 12:48
    2015年3月4日 14:37
    モデレータ

すべての返信

  • こんにちは。

    MVVMでしょうか。
    SQLの結果をリストに入れてバインドさせます。

    public class MainWindowViewModel
    {
        public MainWindowViewModel()
        {
            //SQLからの取得結果
            MyList = new ObservableCollection<HogeData>();
            MyList.Add(new HogeData() { Value = "0", Display = "A" });
            MyList.Add(new HogeData() { Value = "1", Display = "B" });
            MyList.Add(new HogeData() { Value = "2", Display = "C" });
        }
        public ObservableCollection<HogeData> MyList { get; set; }
    }
    
    public class HogeData
    {
        public string Value { get; set; }
        public string Display { get; set; }
    }


    <Window x:Class="WpfApplication1.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:local="clr-namespace:WpfApplication1"
            Title="MainWindow" Height="350" Width="525">
        <Window.DataContext>
            <local:MainWindowViewModel />
        </Window.DataContext>
        <Grid>
            <ComboBox ItemsSource="{Binding MyList}"
                      SelectedValuePath="Value"
                      DisplayMemberPath="Display"/>
        </Grid>
    </Window>

    あまりやったことないですが、コードビハインドだと以下でしょうか。

    public MainWindow()
    {
        InitializeComponent();
    
        //SQLからの取得結果
        var MyList = new ObservableCollection<HogeData>();
        MyList.Add(new HogeData() { Value = "0", Display = "A" });
        MyList.Add(new HogeData() { Value = "1", Display = "B" });
        MyList.Add(new HogeData() { Value = "2", Display = "C" });
        cmb.ItemsSource = MyList;
        cmb.SelectedValuePath = "Value";
        cmb.DisplayMemberPath = "Display";
    }
    

    <Window x:Class="WpfApplication1.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525">
        <Grid>
            <ComboBox Name="cmb" />
        </Grid>
    </Window>
    

    2015年3月4日 12:07
    モデレータ
  • ComboBoxとデータベースとのバインドは DataTable を使った方がいいでしょう。
    しかしコードビハインドで直接 ComboBox とバインドさせる方法は WPF で開発する利点を大きく損ないます。データベースからドメインモデルのコレクションを生成し、ビューモデルを介してバインドさせる方法をお勧めします。具体的な実装は Tak1wa さんが提示されてるので参考になるかと思います。

    「不適切な発言」の濫用はフォーラムの運営を妨げる行為です。ご遠慮ください https://social.msdn.microsoft.com/Forums/ja-JP/0f7b0966-0141-4c1b-b7b9-aed65abf60b6?forum=announceja

    • 回答としてマーク protecyamyam 2015年3月10日 12:48
    2015年3月4日 14:37
    モデレータ
  • ComboBoxとデータベースとのバインドは DataTable を使った方がいいでしょう。

    補足しておきますね。ComboBoxとDataTableは直接バインドできません。なので、ひらぽんさんのブログを紹介しておきます。

    Q029. ComboBox に Datasource は指定できないのですか?
    http://d.hatena.ne.jp/hilapon/20101128/1295832349

    しかしコードビハインドで直接 ComboBox とバインドさせる方法は WPF で開発する利点を大きく損ないます。データベースからドメインモデルのコレクションを生成し、ビューモデルを介してバインドさせる方法をお勧めします。具体的な実装は Tak1wa さんが提示されてるので参考になるかと思います。

    こちらも補足させて下さい。
    今は質問者さんはMVVMで開発されていないようですが、WPFではMVVMで開発することが主流になっています。MVVMはデザインパターンの一つですので、どうしてもMVVMでなければならないということはありませんが、WPFのバインド機能をうまく引き出せるパターンだと思いますので、いずれMVVMで開発されることをおすすめします。
    さて、MVVMで開発されると、ObservableCollectionが良く出てきます。これはコレクションの変更をバインド先に伝える機能を持っているからです。もし、その必要が無いのであれば、ObservableCollectionを使う必要はありません。Listでも十分です。例えばデータベースからselectしてきたレコードの参照しかしないような場合です。その辺りをご判断下さい。


    ★良い回答には回答済みマークを付けよう! MVP - .NET  http://d.hatena.ne.jp/trapemiya/

    • 回答としてマーク protecyamyam 2015年3月10日 12:48
    2015年3月5日 1:14
    モデレータ
  • お二人ともご回答ありがとうございます.

    MVVMについて理解せずに開発をすすめておりましたが、お二人のアドバイスでMVVMについて理解する必要性を感じ、勉強することで所望の機能を実装することが出来ました.

    ListにSQLの結果を格納して表示させることができました.

    2015年3月9日 23:56