2016-07-15 56 views
1

去關閉這個線程:Attach a SQL database to ComboBox.ItemSource (WPF)灌裝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信息編碼:

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代碼:

<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

您正在接近這個錯誤的方式。 WPF被設計爲使用數據綁定和MVVM方法(Model-> View-> ViewModel)很好地工作。您應該閱讀MVVM,因爲它非常強大,並且可以幫助您編寫更好的WPF應用程序。您的Window XAML文件應該只有佈局代碼,並且您想要綁定到某些數據的每個屬性都應該在XAML中使用{Binding}表達式。

例如,如果你想這個組合框的位置列表綁定,您可以使用此XAML:

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

,然後在視圖模型類,你可以公開的屬性稱爲位置返回一個從數據庫中的位置,這樣的名單:

首先創建一個視圖模型類,並實現INotifyPropertyChanged接口:

public class MainViewModel : INotifyPropertyChanged 

然後在類中,您將添加一個公共屬性名爲地點:

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

注意如何我實現了我的ViewModel類INotifyPropertyChanged接口。只要底層模型的屬性發生更改,WPF就會使用此接口來更新UI。當我的位置列表更改時,您可以看到我調用PropertyChanged事件的位置。這告訴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數據庫中的位置列表。因此,創建一個SqlConnection,然後創建一個SqlCommand,然後在您的SqlCommand上調用ExecuteReader並讀取每條記錄,調用Locations.Add(reader.GetString(0));.無論何時將任何內容添加到位置列表,UI都會自行更新。 – Mangist

+1

我不認爲我很清楚。我的意思是逐個添加它們,如您的示例所示。不過,我明白你在說什麼。我會嘗試並報告。感謝您的幫助。 –