locked
Right way to change datagrid row, column, cells background colors in code-behind? RRS feed

  • Frage

  • Hi all,

    I have a winform program that I'm upgrading to wpf (I'm new to wpf). The wpf code for the function (SetdataGridBackgroundColors()) is below with the winform code commented out so I can fix it.  I have a datagrid with a Cornsilk background color alteranating with LightGreen depending on the content of datetime  cell. If the day portion of the datetime is different then the color changes from one to the other. I used a colorIndex variable because at the end of the month it could go from 31 to 1 and that would not work if I use the day directly.

    I tried this line to change the background color:

    optionsDataDatagrid.RowBackground = new SolidColorBrush(Colors.Cornsilk);

    this works but it changes every row. I found this other stuff:

    DataGridRow currentRowColor = optionsDataDatagrid.ItemContainerGenerator.ContainerFromIndex(i) as DataGridRow;
    //DataGridRow currentRowColor = optionsDataDatagrid.ItemContainerGenerator.ContainerFromItem(optionsDataDatagrid.Items[i]) as DataGridRow;
    currentRowColor.Background = new SolidColorBrush(Colors.Cornsilk);

    Either ContainerFromIndex or ContainerFromItem throw an exception because currentRowColor is null. I looked at optionsDataDatagrid.Items[i] and is not null. Then I read that using ItemContainerGenerator is not a good idea.

    BTW I'm calling SetdataGridBackgroundColors() after datagrid is been filled with data.

    So... what is the proper way to set each row, column or cell background color in wpf?

    Thanks

    private void SetdataGridBackgroundColors() { optionRowData rowData = new optionRowData(); if (optionsDataDatagrid.Items.Count == 0) return; int colorIndex = 1; DateTime savedDate, currentRowDate; rowData = optionsDataDatagrid.Items[0] as optionRowData; savedDate = rowData.col_datetime.Date; //only compare the date not the time for (int i = 0; i < optionsDataDatagrid.Items.Count; i++) { //currentRowDate = Convert.ToDateTime(optionsDataDatagrid.Rows[i].Cells[3].Value); //winform code //currentRowDate = currentRowDate.Date; //winform code rowData = optionsDataDatagrid.Items[i] as optionRowData; currentRowDate = rowData.col_datetime.Date; if (currentRowDate != savedDate) { colorIndex++; savedDate = currentRowDate; } if (colorIndex % 2 == 0) { //optionsDataDatagrid.Rows[i].DefaultCellStyle.BackColor = Color.Cornsilk; //------------------- testing new code --------------begin optionsDataDatagrid.RowBackground = new SolidColorBrush(Colors.Cornsilk); //this changes all rows //DataGridRow currentRowColor = optionsDataDatagrid.ItemContainerGenerator.ContainerFromIndex(i) as DataGridRow; //DataGridRow currentRowColor = optionsDataDatagrid.ItemContainerGenerator.ContainerFromItem(optionsDataDatagrid.Items[i]) as DataGridRow; //currentRowColor.Background = new SolidColorBrush(Colors.Cornsilk);

    //------------------- testing new code --------------end //optionsDataDatagrid.Columns[4].DefaultCellStyle.BackColor = Color.DarkSalmon; //optionsDataDatagrid.Columns[5].DefaultCellStyle.BackColor = Color.Aquamarine; //optionsDataDatagrid.Rows[i].Cells[4].Style.ApplyStyle(optionsDataDataGridView.Columns[4].DefaultCellStyle); //optionsDataDatagrid.Rows[i].Cells[5].Style.ApplyStyle(optionsDataDataGridView.Columns[5].DefaultCellStyle); } else { //optionsDataDatagrid.Rows[i].DefaultCellStyle.BackColor = Color.LightGreen; //------------------- testing new code --------------begin optionsDataDatagrid.RowBackground = new SolidColorBrush(Colors.LightGreen); //this has no effect //------------------- testing new code --------------end //optionsDataDatagrid.Columns[4].DefaultCellStyle.BackColor = Color.Coral; //optionsDataDatagrid.Columns[5].DefaultCellStyle.BackColor = Color.LimeGreen; //optionsDataDatagrid.Rows[i].Cells[4].Style.ApplyStyle(optionsDataDataGridView.Columns[4].DefaultCellStyle); //optionsDataDatagrid.Rows[i].Cells[5].Style.ApplyStyle(optionsDataDataGridView.Columns[5].DefaultCellStyle); } } }



    • Bearbeitet DSP1024 Freitag, 23. Januar 2015 18:45
    Freitag, 23. Januar 2015 18:45

Antworten

  • Setting colours in code is dangerous depending on whether the DataGrid is is using virtualization.  In WPF you should never have to access controls in code.  Also trying to translate how you did things in winforms to WPF is a tried and true form of punishment.

    Using databinding and styles to accomplish what you want is not that difficult and will pay dividends in the future for sure.

    Create a collection (an ObservableCollection if you are allowing adding and removing data) and use that as the ItemsSource of the DataGrid.  Once you have created this it will populate the datagrid from the data.  You will need to create simple styles for your columns but there are many examples on the internet and if you could provide more info I might be able to provide a small sample.


    Lloyd Sheen

    • Als Antwort markiert DSP1024 Sonntag, 25. Januar 2015 01:37
    Samstag, 24. Januar 2015 00:30

Alle Antworten

  • Setting colours in code is dangerous depending on whether the DataGrid is is using virtualization.  In WPF you should never have to access controls in code.  Also trying to translate how you did things in winforms to WPF is a tried and true form of punishment.

    Using databinding and styles to accomplish what you want is not that difficult and will pay dividends in the future for sure.

    Create a collection (an ObservableCollection if you are allowing adding and removing data) and use that as the ItemsSource of the DataGrid.  Once you have created this it will populate the datagrid from the data.  You will need to create simple styles for your columns but there are many examples on the internet and if you could provide more info I might be able to provide a small sample.


    Lloyd Sheen

    • Als Antwort markiert DSP1024 Sonntag, 25. Januar 2015 01:37
    Samstag, 24. Januar 2015 00:30
  • I (also) strongly recommend mvvm.

    Setting values is a particularly bad idea in this case.

    I don't mean to be rude but your explanation of the requirement is kind of vague.

    I would bind solidcolourbrushes.

    Set the properties based on whatever your logic is within the viewmodel.

    You can switch out what each of the brushes holds when the user clicks wherever.

    So you use a highlightbrush when something or other is true.

    That highlightbrush is set to a blue brush when the user clicks left and a red brush when they click right.


    Please don't forget to upvote posts which you like and mark those which answer your question.
    My latest Technet article - Dynamic XAML

    Samstag, 24. Januar 2015 10:03