简体   繁体   English

WPF 中数据网格内的静态组合框,但具有由 SQL 设置的选定值

[英]Static combobox within a datagrid in WPF, but have the Selected Value set by SQL

I am trying to use a static list of asset status codes in a combobox, but use an SQL query to pull the appropriate status from an SQL server and use it as the selected value.我试图在组合框中使用资产状态代码的静态列表,但使用 SQL 查询从 SQL 服务器中提取适当的状态并将其用作选定值。

For example, the combobox, would have "Active", "Returned" or "Repair Depot" set, but it would obtain the selected value via the database table Assets which has a field in it called Status.例如,组合框将设置“Active”、“Returned”或“Repair Depot”,但它会通过数据库表 Assets 获取所选值,该表中有一个名为 Status 的字段。

I am having an issue populating the combobox.我在填充组合框时遇到问题。 No errors, but no data either.没有错误,但也没有数据。

The XAML: XAML:

<Window x:Class="Test_Personnel.Dialogs.WinAssets"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:Test_Personnel.Dialogs"
    mc:Ignorable="d"
    Title="Assets" Height="450" Width="800" Loaded="AssetsLoad">
<Grid Margin="0,10,0,0">
    <DataGrid Name="AssetGrid" HorizontalAlignment="Left" Margin="31,57,0,0" VerticalAlignment="Top" ItemsSource="{Binding Path=Assets}" AutoGenerateColumns="False" AlternatingRowBackground="LightBlue" RenderTransformOrigin="0.534,2.99">
        <DataGrid.Columns>
            <DataGridComboBoxColumn Header="Status" ItemsSource="{Binding Status}"/>
            <DataGridTemplateColumn>
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <Button x:Name="Save" Content="Save" Click="Button_Assets_Save_Click" />
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
            <DataGridTextColumn Binding="{Binding Path=AssetType, UpdateSourceTrigger=LostFocus}" Header="Type" Width="auto"/>
            <DataGridTextColumn Binding="{Binding Path=AssetNo, UpdateSourceTrigger=LostFocus}" Header="Asset Number" Width="auto"/>
            <DataGridTextColumn Binding="{Binding Path=AssetSerialNo, UpdateSourceTrigger=LostFocus}" Header="Serial No" Width="auto"/>
            <DataGridTextColumn Binding="{Binding Path=AssetPhoneNo, UpdateSourceTrigger=LostFocus}" Header="Phone No" Width="auto"/>
        </DataGrid.Columns>
    </DataGrid>
    <ComboBox Name="cmbEmployee" SelectedValuePath="Tag" SelectionChanged="CmbEmployee_Changed" HorizontalAlignment="Left" Margin="31,30,0,0" VerticalAlignment="Top" Width="193"/>
</Grid>

The code behind:背后的代码:

/// <summary>
/// Interaction logic for WinAssets.xaml
/// </summary>
public partial class WinAssets : Window
{

    // Create a new string to store the employee ID so we can use it later
    public String strEmpID
    { get; set; }

    // Class for the status portion of the combobox
    public class Option
    {
        public int OptionId { get; set; }
        public string StatusText { get; set; }
    }

    public class BoundObject
    {
        public List<Option> cmbStatus { get; set; }
    }

    readonly SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder
    {
        DataSource = "",
        UserID = "",
        Password = "",
        InitialCatalog = "Personnel",
        PersistSecurityInfo = false,
        MultipleActiveResultSets = false,
        Encrypt = true,
        TrustServerCertificate = false,
        ConnectTimeout = 30
    };

    public WinAssets()
    {
        InitializeComponent();

    }

    // assign the employee ID to the object
    public WinAssets(String strempID):this()
    { this.strEmpID = strempID;
    }


private void AssetsLoad(object sender, RoutedEventArgs e)
    {
        int j = 0;

        SqlConnection connection = new SqlConnection(builder.ConnectionString);
        connection.Open();

        // Create daPersonnel adapter to get employee information so we can use it to select data in ComboBox
        SqlDataAdapter daPersonnel = new SqlDataAdapter("SELECT * FROM Employee", connection);
        DataTable dtPersonnel = new DataTable();
        daPersonnel.Fill(dtPersonnel);

        ComboBoxItem item = new ComboBoxItem();
        item.Content = "All";
        item.Tag = "0";
        cmbEmployee.Items.Add(item);
        for (int i = 0; i < dtPersonnel.Rows.Count; i++)
        {
            ComboBoxItem item1 = new ComboBoxItem();
            item1.Content = dtPersonnel.Rows[i]["LastName"].ToString() + ", " + dtPersonnel.Rows[i]["FirstName"].ToString();
            item1.Tag = dtPersonnel.Rows[i]["EmployeeID"].ToString();
            cmbEmployee.Items.Add(item1);

            //if the string strEmpId is set, then someone requested it via the MainWindow, so get the row (j) corresponding to the appropriate Employee
            if (dtPersonnel.Rows[i]["EmployeeId"].ToString() == strEmpID)
            {
                j = i;
            }
        }

        if (strEmpID != null)
        {
            cmbEmployee.SelectedValue = dtPersonnel.Rows[j]["EmployeeId"].ToString();
        }

        StringBuilder sb = new StringBuilder();
        sb.Append("SELECT EmployeeID, Status, AssetType, AssetNo, AssetPhoneNo, AssetSerialNo FROM Assets WHERE EmployeeID = @strEmpID1;");
        String sql = sb.ToString();

        SqlCommand command = new SqlCommand(sql, connection);
        var strEmpIDparam = new SqlParameter("strEmpID1", SqlDbType.VarChar);
        strEmpIDparam.Value = strEmpID;
        command.Parameters.Add(strEmpIDparam);
        DataTable dt = new DataTable();
        SqlDataAdapter adapter = new SqlDataAdapter(command);
        adapter.Fill(dt);

        // Set status combobox to be selected to what is in the database
        var sOpts = new List<Option> { new Option { StatusText = "Active" }, new Option { StatusText = "Returned" }, new Option { StatusText = "Repair Depot" } };
        var list = new List<BoundObject> { new BoundObject { cmbStatus = sOpts } };

        //AssetGrid.ItemsSource = list;

        AssetGrid.ItemsSource = dt.DefaultView;
        AssetGrid.CanUserAddRows = false;

        daPersonnel.Dispose();
        adapter.Dispose();
        command.Dispose();
        connection.Close();
    }

    private void Filldatagrid()
    {

        int j = 0;

        SqlConnection connection = new SqlConnection(builder.ConnectionString);
        connection.Open();

        // Create daPersonnel adapter to get employee information so we can use it to select data in ComboBox
        SqlDataAdapter daPersonnel = new SqlDataAdapter("SELECT * FROM Employee", connection);
        DataTable dtPersonnel = new DataTable();
        daPersonnel.Fill(dtPersonnel);

        ComboBoxItem item = new ComboBoxItem();
        item.Content = "All";
        item.Tag = "0";
        cmbEmployee.Items.Add(item);
        for (int i = 0; i < dtPersonnel.Rows.Count; i++)
        {
            ComboBoxItem item1 = new ComboBoxItem();
            item1.Content = dtPersonnel.Rows[i]["LastName"].ToString() + ", " + dtPersonnel.Rows[i]["FirstName"].ToString();
            item1.Tag = dtPersonnel.Rows[i]["EmployeeID"].ToString();
            cmbEmployee.Items.Add(item1);

            //if the string strEmpId is set, then someone requested it via the MainWindow, so get the row (j) corresponding to the appropriate Employee
            if (dtPersonnel.Rows[i]["EmployeeId"].ToString() == strEmpID)
            {
                j = i;
            }
        }

        if (strEmpID != null)
        {
            cmbEmployee.SelectedValue = dtPersonnel.Rows[j]["EmployeeId"].ToString();
        }

        StringBuilder sb = new StringBuilder();
        sb.Append("SELECT EmployeeID, Status, AssetType, AssetNo, AssetPhoneNo, AssetSerialNo FROM Assets WHERE EmployeeID = @strEmpID1;");
        String sql = sb.ToString();

        SqlCommand command = new SqlCommand(sql, connection);
        var strEmpID1param = new SqlParameter("strEmpID1", SqlDbType.VarChar);
        strEmpID1param.Value = strEmpID;
        command.Parameters.Add(strEmpID1param);
        DataTable dt = new DataTable();
        SqlDataAdapter adapter = new SqlDataAdapter(command);
        adapter.Fill(dt);

        AssetGrid.ItemsSource = dt.DefaultView;
        AssetGrid.CanUserAddRows = false;

        daPersonnel.Dispose();
        adapter.Dispose();
        command.Dispose();
        connection.Close();

    }

    private void Button_Assets_Save_Click(object sender, RoutedEventArgs e)
    {

    }

    private void CmbEmployee_Changed(object sender, SelectionChangedEventArgs e)
    {

        strEmpID = (string)((ComboBoxItem) cmbEmployee.SelectedItem).Tag; //get value of combobox (the ID)
        int j = 0;

        SqlConnection connection = new SqlConnection(builder.ConnectionString);
        connection.Open();

        // Create daPersonnel adapter to get employee information so we can use it to select data in ComboBox
        SqlDataAdapter daPersonnel = new SqlDataAdapter("SELECT * FROM Employee", connection);
        DataTable dtPersonnel = new DataTable();
        daPersonnel.Fill(dtPersonnel);

        for (int i = 0; i < dtPersonnel.Rows.Count; i++)
        {

            //if the string strEmpId is set, then someone requested it via the MainWindow, so get the row (j) corresponding to the appropriate Employee
            if (dtPersonnel.Rows[i]["EmployeeId"].ToString() == strEmpID)
            {
                j = i;
            }
        }

        if (strEmpID != null)
        {
            cmbEmployee.SelectedValue = strEmpID;
        }

        StringBuilder sb = new StringBuilder();
        if (strEmpID == "0")
        {
            sb.Append("SELECT Employee.FirstName, Employee.LastName, Assets.EmployeeID, Assets.AssetType, Assets.AssetNo, Assets.AssetPhoneNo, Assets.AssetSerialNo, Assets.Status FROM Assets JOIN Employee ON Assets.EmployeeID = Employee.EmployeeId;");
            DataGridTextColumn textColumnFN = new DataGridTextColumn();
            AssetGrid.AutoGenerateColumns = false;
            textColumnFN.Header = "First Name";
            textColumnFN.Binding = new Binding("FirstName");
            AssetGrid.Columns.Add(textColumnFN);
            DataGridTextColumn textColumnLN = new DataGridTextColumn();
            textColumnLN.Header = "Last Name";
            textColumnLN.Binding = new Binding("LastName");
            AssetGrid.Columns.Add(textColumnLN);
        }
        else
        {
            // If AssetGrid has more than 4 columns than someone selected all, which needs FirstName, LastName, but now we don't need those
            if (AssetGrid.Columns.Count > 6)
            { 
                AssetGrid.Columns.RemoveAt(6);  // Remove First Name column
                AssetGrid.Columns.RemoveAt(6);  // Since we removed First Name column, Last Name Column is now column 6, remote it too.
            }
            sb.Append("SELECT EmployeeID, Status, AssetType, AssetNo, AssetPhoneNo, AssetSerialNo FROM Assets WHERE EmployeeID = @strEmpID1;");
        }

        String sql = sb.ToString();

        SqlCommand command = new SqlCommand(sql, connection);
        var strEmpID1param = new SqlParameter("strEmpID1", SqlDbType.VarChar);
        strEmpID1param.Value = strEmpID;
        command.Parameters.Add(strEmpID1param);
        DataTable dt = new DataTable();
        SqlDataAdapter adapter = new SqlDataAdapter(command);
        adapter.Fill(dt);

        AssetGrid.ItemsSource = dt.DefaultView;
        AssetGrid.CanUserAddRows = false;

        daPersonnel.Dispose();
        adapter.Dispose();
        command.Dispose();
        connection.Close();
    }

}

} }

What I am mainly working on right now is the AssetsLoad.我现在主要在做的是AssetsLoad。 If I can get it to work on loading, I think I can handle the rest.如果我能让它在加载时工作,我想我可以处理剩下的事情。

I cannot get the combobox to either load any of the static data or the datafrom the SQL server.我无法让组合框加载任何静态数据或来自 SQL 服务器的数据。

Thank you, in advance!先感谢您!

Image of broken combobox损坏的组合框的图像

I guess you are not familiar with WPF programming.我猜你不熟悉 WPF 编程。 I think you want to binding "Status" to ComboBoxColumn ItemsSsource.我认为您想将“Status”绑定到 ComboBoxColumn ItemsSsource。

<Window x:Class="Test_Personnel.Dialogs.WinAssets"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:Test_Personnel.Dialogs"
    mc:Ignorable="d" x:Name="mainWnd"
    Title="Assets" Height="450" Width="800" Loaded="AssetsLoad">
<Grid Margin="0,10,0,0">
    <DataGrid Name="AssetGrid" HorizontalAlignment="Left" Margin="31,57,0,0" VerticalAlignment="Top" ItemsSource="{Binding Path=Assets}" AutoGenerateColumns="False" AlternatingRowBackground="LightBlue" RenderTransformOrigin="0.534,2.99">
        <DataGrid.Columns>
            <DataGridComboBoxColumn Header="Status" ItemsSource="{Binding Status,ElementName=MainWnd}" DisplayMemberPath="StatusText" />
            <DataGridTemplateColumn>
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <Button x:Name="Save" Content="Save" Click="Button_Assets_Save_Click" />
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
            <DataGridTextColumn Binding="{Binding Path=AssetType, UpdateSourceTrigger=LostFocus}" Header="Type" Width="auto"/>
            <DataGridTextColumn Binding="{Binding Path=AssetNo, UpdateSourceTrigger=LostFocus}" Header="Asset Number" Width="auto"/>
            <DataGridTextColumn Binding="{Binding Path=AssetSerialNo, UpdateSourceTrigger=LostFocus}" Header="Serial No" Width="auto"/>
            <DataGridTextColumn Binding="{Binding Path=AssetPhoneNo, UpdateSourceTrigger=LostFocus}" Header="Phone No" Width="auto"/>
        </DataGrid.Columns>
    </DataGrid>
    <ComboBox Name="cmbEmployee" SelectedValuePath="Tag" SelectionChanged="CmbEmployee_Changed" HorizontalAlignment="Left" Margin="31,30,0,0" VerticalAlignment="Top" Width="193"/>
</Grid>

but your code doesn't have Status property.但您的代码没有 Status 属性。 write it.写下来。

public List<Option> Status { get; set; }

rewrite init status.重写初始化状态。

Status = new List<Option> { new Option { StatusText = "Active" }, new Option { StatusText = "Returned" }, new Option { StatusText = "Repair Depot" } };

try it.尝试一下。 Good Luck!祝你好运!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM