2016-07-15 5 views
1

とWPFコンボボックスを埋める:Attach a SQL database to ComboBox.ItemSource (WPF)SQL列このスレッドのオフに行く

私はまだ実行する方法について混乱しています。以下は私のGUIのための私のコードです。私はC#が初めてで、コンボボックスの操作方法が不明です。

私はSQLクエリからデータを取得し、コンボボックスの値を入力しようとしています。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Data; 
using System.Windows.Documents; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Media.Imaging; 
using System.Windows.Navigation; 
using System.Windows.Shapes; 

namespace List 
{ 
    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 
      var instance = new SQLInformation(); 
      instance.fillComboBox("Data Source=server Initial Catalog=db; User id=user; Password=pass;", System.Windows.Controls.ComboBox. , "select distinct [location] from [dbo].[locations]", null, "[location]"); 
     } 
    } 

} 

SQL情報コード:

<Window x:Class="List.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="FirstWindow" Height="390" Width="683"> 
    <Window.Background> 
     <LinearGradientBrush StartPoint='0,0' EndPoint='0,1'> 
      <LinearGradientBrush.GradientStops> 
       <GradientStop Color='#FFC1C1C1' Offset="0.99" /> 
       <GradientStop Color='White' /> 
       <GradientStop Color="#FFE4E4E4" Offset="0.397"/> 
       <GradientStop Color="#FFD1D1D1" Offset="0.777"/> 
      </LinearGradientBrush.GradientStops> 
     </LinearGradientBrush> 
    </Window.Background> 
    <Grid>   
     <Grid Height="360" VerticalAlignment="Top"> 
      <Image HorizontalAlignment="Left" Height="50" Margin="119,10,0,0" VerticalAlignment="Top" Width="270" Source=""/> 
      <Image HorizontalAlignment="Left" Height="23" Margin="153,50,0,0" VerticalAlignment="Top" Width="209" Source=""/> 

      <ComboBox x:Name="LocationComboBox" HorizontalAlignment="Left" Margin="153,122,0,0" VerticalAlignment="Top" Width="73" SelectedIndex="0"> 

      </ComboBox> 

     </Grid> 

    </Grid> 
</Window> 

答えて

2

あなたはこれを近づいている間違った方法:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Data.SqlClient; 
using System.Data; 
using System.Collections.Specialized; 
using System.Configuration; 


namespace List 
{ 
    public class SQLInformation 
    { 
     public bool fillComboBox(string connectionString, System.Windows.Controls.ComboBox combobox, string query, string defaultValue, string itemText) 
     { 
      SqlCommand sqlcmd = new SqlCommand(); 
      SqlDataAdapter sqladp = new SqlDataAdapter(); 
      DataSet ds = new DataSet(); 


      try 
      { 
       using (SqlConnection _sqlconTeam = new SqlConnection(ConfigurationManager.ConnectionStrings[connectionString].ConnectionString)) 
       { 
        sqlcmd.Connection = _sqlconTeam; 
        sqlcmd.CommandType = CommandType.Text; 
        sqlcmd.CommandText = query; 
        _sqlconTeam.Open(); 
        sqladp.SelectCommand = sqlcmd; 
        sqladp.Fill(ds, "defaultTable"); 
        DataRow nRow = ds.Tables["defaultTable"].NewRow(); 
        nRow[itemText] = defaultValue; 
        ds.Tables["defaultTable"].Rows.InsertAt(nRow, 0); 
        combobox.DataContext = ds.Tables["defaultTable"].DefaultView; 

        combobox.DisplayMemberPath = ds.Tables["defaultTable"].Columns[0].ToString(); 
        combobox.SelectedValuePath = ds.Tables["defaultTable"].Columns[1].ToString(); 
       } 
       return true; 
      } 
      catch (Exception expmsg) 
      { 
       return false; 
      } 
      finally 
      { 
       sqladp.Dispose(); 
       sqlcmd.Dispose(); 
      } 
     } 
    } 
} 

は、ここに私のXAMLコードです。 WPFは、データバインディングとMVVMメソドロジ(Model-> View-> ViewModel)を使用してうまく動作するように設計されています。あなたは非常に強力で、より良いWPFアプリケーションを書くのに役立つので、MVVMでいくつかの読書をする必要があります。あなたのウィンドウXAMLファイルはレイアウトコードを持つだけで、いくつかのデータにバインドする各プロパティはXAMLの{Binding}式を使用する必要があります。

あなたが場所のリストに、このコンボボックスをバインドしたい場合たとえば、あなたがこのXAMLを使用することができます。

<ComboBox ItemsSource="{Binding Locations}" /> 

そしてあなたのViewModelクラスで、あなたはA返す場所と呼ばれるプロパティを公開することができますこのようなデータベースから場所のリスト:次に

public class MainViewModel : INotifyPropertyChanged 

まずINotifyPropertyChangedインターフェイスをViewModelにクラスを作成し、実装します私は私のViewModelクラスにINotifyPropertyChangedのインターフェイスを実装しましたか

private ObservableCollection<string> _locations; 
    public ObservableCollection<string> Locations 
    { 
     get { return _locations; } 
     set 
     { 
      _locations = value; 
      PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Locations")); 
     } 
    } 

は注意:クラスの中、あなたは場所と呼ばれるパブリックプロパティを追加します。このインターフェイスは、基になるモデルのプロパティが変更されるたびにUIを更新するためにWPFで使用されます。 Locationsリストが変更されたときに、PropertyChangedイベントを呼び出す場所を確認することができます。これは、LocationsにバインドされているUIコントロールを更新する必要があることをUIに通知します。あなたのMainWindow.xaml.csファイルのコンストラクタで

、あなたは、このビューモデルの新しいインスタンスへのDataContextを設定する必要があります。

public MainWindow() 
    { 
     InitializeComponent(); 

     DataContext = new MainViewModel(); 
    } 

そして、これが私の最後のMainViewModelクラスは次のようになります。あなたは場所のリストを移入するためにいくつかの実際のデータベース・コードと私のコードを置き換えることができます。

public class MainViewModel : INotifyPropertyChanged 
{ 
    private ObservableCollection<string> _locations; 
    public ObservableCollection<string> Locations 
    { 
     get { return _locations; } 
     set 
     { 
      _locations = value; 
      PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Locations")); 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    public MainViewModel() 
    { 
     // Load our locations from the database here 
     // You can instead populate yours from SQL 
     Locations = new ObservableCollection<string>(); 
     Locations.Add("Location 1"); 
     Locations.Add("Location 2"); 
     Locations.Add("Location 3"); 
     Locations.Add("Location 4"); 

     // Now your combobox should be populated 
    } 
} 
+0

これは私が前に持っていたし、それがアイテムを手動で入力するための完璧に働いたものです。私はSQL Serverからデータを追加しようとしたときに立ち往生しました。したがって、私は別のルートを行った。私は、配列にSQL値を格納し、その後、指定されたメソッドを使用してコンボボックスに追加するためにforループを使用する必要があると仮定します。これは有効な方向ですか? –

+0

いいえ、手動でコンボボックスに何も追加しないでください。 SQLデータベースからLocationsのリストを作成します。したがって、SqlConnectionを作成し、次にSqlCommandを作成し、SqlCommandでExecuteReaderを呼び出してLocations.Add(reader.GetString(0));を呼び出して各レコードを読み取ります。 Locationsリストに何かを追加すると、UIが自動的に更新されます。 – Mangist

+1

私ははっきりとは思わなかった。あなたの例に示されているように、私はそれらを一つずつ追加することを意味しました。それにもかかわらず、私はあなたが言っていることを理解しています。私はそれを試み、報告するつもりです。お手伝いありがとう。 –