[英]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.