WPF DataGrid индивидуальный цвет строки - PullRequest
0 голосов
/ 24 сентября 2019

У меня есть два датагрида.DG1 и DG2 с одним столбцом A (каждый) и несколькими строками.Задача состоит в том, чтобы выделить конкретную строку в одной сетке данных, когда пользователь выбирает строку с таким же значением в другой сетке данных.Пример: пользователь выбирает строку 5 DG1, столбец A, значение которого равно «ABC».«ABC» - это строка 23, столбец A в DG2.Следовательно, строка 23 DG должна быть выделена красным цветом.Это должно работать наоборот (щелчок по строке 23 в DG2 должен выделить строку 5 в DG1).В настоящее время мой код работает, вызывая свойство SelectedItem Datagrid.И обратной стороной этого является то, что существует бесконечный цикл выбора, т.е. когда пользователь выбирает строку 5 из DG1, он выбирает строку 23 из DG2, которая затем запускает выбор для строки 5 из DG1, которая затем запускает выбор из строки 23 из DG2.Таким образом, решение моей проблемы может заключаться в том, чтобы либо решить эту проблему с бесконечным циклом, либо предоставить способ выделить конкретную строку сетки данных определенным цветом, исключив тем самым вызов свойства 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;

    }

1 Ответ

0 голосов
/ 24 сентября 2019

Написание кода в коде позади окна или элемента управления не рекомендуется в 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;
}
...