簡體   English   中英

WPF 中數據網格內的靜態組合框,但具有由 SQL 設置的選定值

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

我試圖在組合框中使用資產狀態代碼的靜態列表,但使用 SQL 查詢從 SQL 服務器中提取適當的狀態並將其用作選定值。

例如,組合框將設置“Active”、“Returned”或“Repair Depot”,但它會通過數據庫表 Assets 獲取所選值,該表中有一個名為 Status 的字段。

我在填充組合框時遇到問題。 沒有錯誤,但也沒有數據。

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>

背后的代碼:

/// <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();
    }

}

}

我現在主要在做的是AssetsLoad。 如果我能讓它在加載時工作,我想我可以處理剩下的事情。

我無法讓組合框加載任何靜態數據或來自 SQL 服務器的數據。

先感謝您!

損壞的組合框的圖像

我猜你不熟悉 WPF 編程。 我認為您想將“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>

但您的代碼沒有 Status 屬性。 寫下來。

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

重寫初始化狀態。

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

嘗試一下。 祝你好運!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM