使用SQL列填充WPF Combobox

时间:2016-07-15 14:43:55

标签: c# sql visual-studio xaml user-interface

离开这个主题:Attach a SQL database to ComboBox.ItemSource (WPF)

我仍然对如何执行感到困惑。下面是我的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>

1 个答案:

答案 0 :(得分:2)

你正以错误的方式接近这一点。 WPF旨在使用数据绑定和MVVM方法(Model-&gt; View-&gt; ViewModel)很好地工作。你应该对MVVM做一些阅读,因为它非常强大,可以帮助你编写更好的WPF应用程序。您的Window XAML文件应该只有布局代码,并且您希望绑定到某些数据的每个属性都应该在XAML中使用{Binding}表达式。

例如,如果要将此ComboBox绑定到位置列表,则可以使用此XAML:

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

然后在ViewModel类中,您可以公开一个名为Locations的属性,该属性返回数据库中的位置列表,如下所示:

首先创建一个ViewModel类并实现INotifyPropertyChanged接口:

public class MainViewModel : INotifyPropertyChanged

然后在课程中添加一个名为Locations:

的公共属性
    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它应该更新绑定到Locations的任何UI控件。

在MainWindow.xaml.cs文件的构造函数中,您应该将DataContext设置为此ViewModel的新实例:

    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
    }
}