C# WPF DataGrid 搜索列中的值,返回行索引
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28860612/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C# WPF DataGrid Search for a Value in a Column, Return the Row Index
提问by RJP
I am new at C# development. I am learning and struggling as I am writing an application - the best way to learn is by doing : )
我是 C# 开发的新手。我在编写应用程序时正在学习和挣扎 - 最好的学习方法是做:)
I hope that someone will be able to assist me with my issue.
我希望有人能够帮助我解决我的问题。
I am populating the WPF DataGridvia the dataGrid1.ItemsSource = dt.DefaultView;and then letting the DataGrid automatically generate the columns for me.
我正在通过dataGrid1.ItemsSource = dt.DefaultView;填充WPF DataGrid ; 然后让 DataGrid 自动为我生成列。
The user is able to click on any row in the DataGrid which will then populate the header section that I have on the WPF UI with the row's data - this allows the user to edit the row via the header. I do not want them to edit via the DataGrid.
用户可以单击 DataGrid 中的任何行,然后将使用该行的数据填充我在 WPF UI 上的标题部分 - 这允许用户通过标题编辑该行。我不希望他们通过 DataGrid 进行编辑。
The user is able to edit the row via the header fields and then click on an UPDATE button. The UPDATE button will run a stored procedure which handles all validations and updating of the record. Once the record is saved I fire off the grid refresh method.
用户可以通过标题字段编辑行,然后单击更新按钮。UPDATE 按钮将运行处理所有验证和记录更新的存储过程。保存记录后,我会触发网格刷新方法。
Once the grid is refreshed I need to be able to search on a specific column on the DataGrid in order to Select, set Focus and scroll into the row that just got updated.
网格刷新后,我需要能够在 DataGrid 上的特定列上进行搜索,以便选择、设置焦点并滚动到刚刚更新的行。
I have searched like crazy on Google and I just cannot find how to do this on the DataGrid. There are samples on how to do it on the DataGridView which is not what I am using.
我在 Google 上疯狂搜索,但在 DataGrid 上找不到如何执行此操作。有关于如何在 DataGridView 上执行此操作的示例,这不是我正在使用的。
Any help is greatly appreciated....thanks
非常感谢任何帮助....谢谢
This is my code for the Button Click
这是我的按钮单击代码
private void btn_Update_Click(object sender, RoutedEventArgs e) {
私有无效 btn_Update_Click(对象发送者,RoutedEventArgs e){
// variables
bool isOkToUpdate = true;
this.Cursor = Cursors.Wait;
// Validations of certain fields
if (txt_FinanceEmpName.Text.Length > 25 )
{
MessageBox.Show("The Finance Emp Name must not exceed 25 characters in length. "
+ txt_FinanceEmpName.Text.Length.ToString()
, "Maximum characters exceeded"
, MessageBoxButton.OK, MessageBoxImage.Stop);
isOkToUpdate = false;
}
//
if (isOkToUpdate == true)
{
// create an instance
DatabaseClass objDatabaseClass = new DatabaseClass(_connectionString);
// if we are able to open and close the SQL Connection then proceed
if (objDatabaseClass.CheckSQLConnection())
{
try
{
// create instance of SqlConnection class. variable 'con' will hold the instance
SqlConnection con = new SqlConnection(_connectionString);
con.Open();
// use a using for all disposable objects, so that you are sure that they are disposed properly
using (SqlCommand cmd = new SqlCommand("usp_mktdata_update_cm_mktdata_emp_name_fits_to_finance", con))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("@IdUnique", SqlDbType.Int).Value = Convert.ToInt32(txt_IdUnique.Text);
cmd.Parameters.Add("@FinanceEmpName", SqlDbType.VarChar).Value = txt_FinanceEmpName.Text;
cmd.Parameters.Add("@ADWindowsLogon", SqlDbType.VarChar).Value = _windowsUserName;
cmd.Parameters.Add("@ADWindowsLogonEMail", SqlDbType.VarChar).Value = _windowsUserNameEMail;
cmd.Parameters.Add("@IndActive", SqlDbType.TinyInt).Value = 1;
cmd.Parameters.Add("@RecordVersion", SqlDbType.Int).Value = Convert.ToInt32(txt_RecordVersion.Text);
//cmd.Parameters.Add("@IdJob", SqlDbType.Int).Value = "DEFAULT";
//cmd.Parameters.Add("@IdUser", SqlDbType.Int).Value = "DEFAULT";
//cmd.Parameters.Add("@outIdUnique", SqlDbType.Int).Value = "DEFAULT";
//cmd.Parameters.Add("@outRecordVersion", SqlDbType.Int).Value = "DEFAULT";
//cmd.Parameters.Add("@outInd", SqlDbType.Int).Value = "DEFAULT";
//cmd.Parameters.Add("@outMessage", SqlDbType.VarChar).Value = "DEFAULT";
cmd.ExecuteNonQuery();
}
// Last Updated Record
txt_LastUpdated_IdUnique.Text = txt_IdUnique.Text;
txt_LastUpdated_FitsEmpName.Text = txt_FitsEmpName.Text;
txt_LastUpdated_FinanceEmpName.Text = txt_FinanceEmpName.Text;
// Refresh the Datagrid - the DataGrid_MonikerName
// pass in null for the params in order to fire the event
btn_RefreshGrid_Click(null, null);
// ****************************************
// TODO: After Grid Refresh Search the column ID UNIQUE for the value stored in txt_IdUnique.Text which
// was just saved via the stored procedure
// Once the value is found in the DataGrid need to grab the DataGrid Row INdex in order to
// Select the ROW and Set the ROW to the SELECTED ROW and set focus to the DataGrid also will need to Scroll the Grid into View.
//
// ****************************************
con.Close();
}
catch (SqlException ex)
{
MessageBox.Show(ex.ToString());
}
}
else
{
MessageBox.Show("Connection not established to the SQL Server. " + Environment.NewLine + "The SQL Server may be offline or valid credentials are not yet granted.", "SQL Server Connection Error", MessageBoxButton.OK, MessageBoxImage.Error);
this.Close();
}
}
this.Cursor = Cursors.Arrow;
}
回答by DRapp
I too work with DataTable.DefaultView for the grids in our system. I have also sub-classed the DataGrid for "MyDataGrid"... On the MyDataGrid, I have a custom method to force loading the given ID based on its primary key. So I have another custom property on the grid for what is the name of the primary key column as it should be found within the dataview, even though it may not be visually shown in the grid.
我也使用 DataTable.DefaultView 来处理我们系统中的网格。我还为“MyDataGrid”对 DataGrid 进行了子分类...在 MyDataGrid 上,我有一个自定义方法可以根据主键强制加载给定的 ID。所以我在网格上有另一个自定义属性,主键列的名称是什么,因为它应该在数据视图中找到,即使它可能不会在网格中直观地显示出来。
Based on what you supplied, here is a modification from my original code to your specific environment...
根据您提供的内容,这是从我的原始代码到您的特定环境的修改...
public void TryGridRefresh()
{
int IDToFind = Convert.ToInt32(txt_IdUnique.Text);
if (IDToFind > -1 && dataGrid1.ItemsSource is DataView )
{
foreach( DataRowView drv in (DataView)dataGrid1.ItemsSource )
if ((int)drv["IdUnique"] == IDToFind)
{
// This is the data row view record you want...
dataGrid1.SelectedItem = drv;
}
}
}
So, just after your call to
所以,在你打电话之后
btn_RefreshGrid_Click(null, null);
then call
然后打电话
TryGridRefresh();
I have my data grids as an entire ROW for the selected value instead of per-cell. So you may need to play around with the object references a bit... Once you find the row, you may also try with dataGrid1.CurrentItem...
我将数据网格作为所选值的整个 ROW 而不是每个单元格。因此,您可能需要稍微处理一下对象引用...一旦找到该行,您还可以尝试使用 dataGrid1.CurrentItem...
Hopefully this will get you closer to your final resolution.
希望这能让您更接近最终的解决方案。
回答by RJP
public void TryGridRefresh(string IdUniqueToFind, DataGrid MyDataGrid, string MyGridColumnToSearch)
{
int IDToFind = Convert.ToInt32(IdUniqueToFind);
// this if did not work for me..got errors
//if (IDToFind > -1) and (dataGrid_MonikerName.ItemsSource is DataView )
//{
foreach (DataRowView drv in (DataView)MyDataGrid.ItemsSource)
{
if ((int)drv[MyGridColumnToSearch] == IDToFind)
{
// This is the data row view record you want...
MyDataGrid.SelectedItem = drv;
MyDataGrid.ScrollIntoView(drv);
MyDataGrid.Focus();
break;
}
}
}
The Method is then called like so after the grid refresh call - TryGridRefresh(txt_LastUpdated_IdUnique.Text, dataGrid_MonikerName, gridData_ColumnToSearch);
然后在网格刷新调用之后调用方法 - TryGridRefresh(txt_LastUpdated_IdUnique.Text, dataGrid_MonikerName, gridData_ColumnToSearch);
I also had to change the
datagrid DataRowView from CurrentCell.Item to SelectedItem in order to capture the entire row for the selected value instead of per-cell.
我还必须将
数据网格 DataRowView 从 CurrentCell.Item更改为 SelectedItem,以便捕获所选值的整行而不是每个单元格。
//DataRowView _DataView = dataGrid_MonikerName.CurrentCell.Item as DataRowView; DataRowView _DataView = dataGrid_MonikerName.SelectedItem as DataRowView;
//DataRowView _DataView = dataGrid_MonikerName.CurrentCell.Item as DataRowView; DataRowView _DataView = dataGrid_MonikerName.SelectedItem 作为 DataRowView;

