【问题标题】:Filling WPF Combobox with SQL Column用 SQL 列填充 WPF 组合框
【发布时间】:2016-07-15 14:43:54
【问题描述】:

离开这个话题: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>

【问题讨论】:

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


    【解决方案1】:

    您以错误的方式处理此问题。 WPF 旨在使用数据绑定和 MVVM 方法(模型->视图->视图模型)很好地工作。您应该阅读 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 类的样子。你可以用一些真实的数据库代码替换我的代码来填充 Locations 列表:

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

    【讨论】:

    • 这是我以前所拥有的,它可以完美地用于手动输入项目。尝试从 SQL Server 添加数据时卡住了。于是,我走了一条替代路线。我假设我应该将 SQL 值存储在一个数组中,然后使用 for 循环使用您指定的方法将它们添加到组合框中。这是一个有效的方向吗?
    • 不,您不应该手动向组合框添加任何内容。从您的 SQL 数据库中填充位置列表。因此,创建一个 SqlConnection,然后创建一个 SqlCommand,然后在 SqlCommand 上调用 ExecuteReader 并读取每条记录,调用 Locations.Add(reader.GetString(0));。每当您向 Locations 列表添加任何内容时,UI 都会自行更新。
    • 我想我不是很清楚。我的意思是一一添加,如您的示例所示。不过,我明白你在说什么。我将尝试并报告。感谢您的帮助。
    • 当然,我会很高兴看到它@ChasenBettinger
    • 在 Google 聊天 @ChasenBettinger 上试试我
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-24
    • 2020-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多