我有两个数据网格。 DG1和DG2具有一列A(每列)和许多行。当用户在另一个数据网格中选择具有相同值的行时,任务是突出显示一个数据网格中的特定行。示例:用户选择DG1第5行第A列,其值为'ABC'。 “ ABC”是DG2中的第23行A列。因此,DG的第23行应以“红色”突出显示。 反之亦然(单击DG2的第23行应突出显示DG1的第5行)。 目前,我的代码通过调用Datagrid的SelectedItem属性来工作。不利的一面是选择存在无限循环,即当用户选择DG1的第5行时,它选择DG2的第23行,然后对DG1的第5行进行选择,然后对DG2的第23行进行选择。 因此,解决我的问题的方法既可以解决此无限循环问题,也可以提供一种方法来突出显示具有特定颜色的数据网格的特定行,从而完全消除对数据网格的selecteditem属性的调用。
下面是一些代码:
//This is the function invoked when a user selects a row in a DG1
private void DG1SelectedItem(object sender, SelectionChangedEventArgs e)
{
if (DG1.SelectedItem != null)
{
var val = DG1.SelectedItem; //Get the paticular row that was selected
DataRowView row = (DataRowView)val;
object[] list = row.Row.ItemArray;
String rowValue = list[0].ToString(); //get the value within that selected row
HighLightRow(DG2, account); //Call a function that highlights a particular row in a Datagrid with a given string value
}
}
//This is the function invoked when a user selects a row in a DG2
private void DG2SelectedItem(object sender, SelectionChangedEventArgs e)
{
if (DG2.SelectedItem != null)
{
var val = DG2.SelectedItem; //Get the paticular row that was selected
DataRowView row = (DataRowView)val;
object[] list = row.Row.ItemArray;
String rowValue = list[0].ToString(); //get the value within that selected row
HighLightRow(DG1, account); //Call a function that highlights a particular row in a Datagrid with a given string value
}
}
//Function to highlight the row in datagrid 'dg' with value of 'value' (only checks first column)
private void HighLightRow(DataGrid dg, string value)
{
dg.UnselectAll();
var itemsource = dg.ItemsSource as IEnumerable;
int index = 0;
ArrayList rowIndices = new ArrayList();
//loop through entire datagrid looking for the string 'value' in the first column
//if found, store the index in an array so it can be utillized to highlight all rows later on
foreach (var item in itemsource)
{
DataRowView row = item as DataRowView;
object[] list = row.Row.ItemArray;
String valueToFind = list[0].ToString();
if (valueToFind.Equals(value))
rowIndices.Add(index);
index++;
}
//For all rows where the string 'value' was foung in the first column of the datagrid, highlight it
//Currently the implementation relies on SelectedItem
for (int i = 0; i < rowIndices.Count; i++)
{
object item = dg.Items[(int)rowIndices[i]];
dg.SelectedItem = item; //this code then invokes DG2SelectedItem (or DG1SelectedItem depending on which SelectedItem function was initially invoked) and we have the inifite loop problem
**/*
This is where I would like to select the row at the indices stored in rowIndices and highlight them red (and not rely on dg.SelectedItem like in the line above)
Something like:
dg.Row[i].Background = Brushes.Red;
*/**
int m = dg.SelectedIndex;
dg.UpdateLayout();
dg.ScrollIntoView(dg.Items[m]);
}
dg.LoadingRow += Dg_LoadingRow;
}
答案 0 :(得分:0)
在WPF中,建议不要在“窗口”或“控件”后面的代码中编写代码。使用MVVM方法要优越得多。您应该考虑转向该范例。
话虽如此,解决您的问题很简单。只需引入一个名为UpdateFlag
的全局变量即可。在每个网格处理程序的开始处将其设置为true
,在处理程序末尾将其设置为false
。在每个处理程序的最开始(设置标志之前),检查此标志是否为true
,如果是这种情况,则立即退出处理程序。这将停止选择更改的无限递归。
类似这样的东西:
private bool UpdateFlag = false;
private void FirstHandler()
{
if(UpdateFlag) return;
UpdateFlag = true;
//Do your highlighting here
UpdateFlag = false;
}
private void SecondHandler()
{
if(UpdateFlag) return;
UpdateFlag = true;
//Do your highlighting here
UpdateFlag = false;
}