使用 SQL 列填充 WPF 组合框

本文关键字:组合 WPF 填充 SQL 使用 | 更新日期: 2023-09-27 17:57:20

离开此线程:将 SQL 数据库附加到 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>

使用 SQL 列填充 WPF 组合框

你以错误的方式接近这个。WPF 旨在使用数据绑定和 MVVM 方法(模型>视图>视图模型)很好地工作。您应该对 MVVM 进行一些阅读,因为它非常强大,可以帮助您编写更好的 WPF 应用程序。窗口 XAML 文件应仅具有布局代码,并且要绑定到某些数据的每个属性都应在 XAML 中使用 {Binding} 表达式。

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

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

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

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

public class MainViewModel : INotifyPropertyChanged

然后在类中,您将添加一个名为 Location 的公共属性:

    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 设置为此 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
    }
}