I have the RadGrid properly changing the row backcolor based on the value of one column by utilizing the RowFormatting event handler, but this causes the selected row backcolor to no longer be the normal blue. Is there a way to set the row backcolor without effecting the selected row backcolor?
Thanks,
Greg Swope
8 Answers, 1 is accepted
In order to achieve your task, you need to apply the color only for the default visual state of the row. For this purpose, you need to use the theme values override API: Override Theme Settings at Run-time:
private
void
radGridView1_RowFormatting(
object
sender, Telerik.WinControls.UI.RowFormattingEventArgs e)
{
if
((
int
)e.RowElement.RowInfo.Cells[0].Value == 5)
{
e.RowElement.DrawFill =
true
;
e.RowElement.GradientStyle = GradientStyles.Solid;
e.RowElement.SetThemeValueOverride(VisualElement.BackColorProperty, Color.LightGreen,
""
);
}
else
{
e.RowElement.ResetValue(LightVisualElement.DrawFillProperty, ValueResetFlags.Local);
e.RowElement.ResetValue(LightVisualElement.GradientStyleProperty, ValueResetFlags.Local);
e.RowElement.ResetThemeValueOverrides();
}
}
I am also sending you a short video showing the result on my end.
I hope this helps. Should you have further questions please do not hesitate to write back.
Regards,
Hristo Merdjanov
Telerik by Progress
Here is my RowFormatting event handler;
private void grdWeekendAssistance_RowFormatting(object sender, RowFormattingEventArgs e)
{
if (!e.RowElement.RowInfo.IsSelected)
{
if ((int)e.RowElement.RowInfo.Cells["RelationshipFlag"].Value == 1)
{
e.RowElement.DrawFill = true;
e.RowElement.GradientStyle = GradientStyles.Solid;
//e.RowElement.BackColor = Color.Red;
e.RowElement.SetDefaultValueOverride(VisualElement.BackColorProperty, Color.Red);
}
else if ((int)e.RowElement.RowInfo.Cells["LimitedAdvocacyFlag"].Value == 1)
{
e.RowElement.DrawFill = true;
e.RowElement.GradientStyle = GradientStyles.Solid;
//e.RowElement.BackColor = Color.Orange;
e.RowElement.SetDefaultValueOverride(VisualElement.BackColorProperty, Color.Orange);
}
else if ((int)e.RowElement.RowInfo.Cells["AssociateLanguageID"].Value == (int)Common.Lib.Language.Spanish)
{
e.RowElement.DrawFill = true;
e.RowElement.GradientStyle = GradientStyles.Solid;
//e.RowElement.BackColor = Color.Green;
e.RowElement.SetDefaultValueOverride(VisualElement.BackColorProperty, Color.Green);
}
else if ((int)e.RowElement.RowInfo.Cells["CampaignSubTypeID"].Value != (int)Common.Lib.CampaignSubtype.WeekendAssignment &&
(int)e.RowElement.RowInfo.Cells["CampaignSubTypeID"].Value != (int)Common.Lib.CampaignSubtype.Salesians &&
(int)e.RowElement.RowInfo.Cells["CampaignSubTypeID"].Value != (int)Common.Lib.CampaignSubtype.PreciousBlood)
{
e.RowElement.DrawFill = true;
e.RowElement.GradientStyle = GradientStyles.Solid;
//e.RowElement.BackColor = Color.LightBlue;
e.RowElement.SetDefaultValueOverride(VisualElement.BackColorProperty, Color.LightBlue);
}
else if (e.RowElement.RowInfo.Cells["AssociateState"].Value.ToString() != e.RowElement.RowInfo.Cells["HLState"].Value.ToString())
{
e.RowElement.DrawFill = true;
e.RowElement.GradientStyle = GradientStyles.Solid;
//e.RowElement.BackColor = Color.Yellow;
e.RowElement.SetDefaultValueOverride(VisualElement.BackColorProperty, Color.Yellow);
}
else
{
//if (e.RowElement.IsOdd && !e.RowElement.IsSelected)
//{
// e.RowElement.DrawFill = true;
// e.RowElement.GradientStyle = GradientStyles.Solid;
// e.RowElement.BackColor = Color.Gainsboro;
//}
//else
//{
e.RowElement.ResetValue(LightVisualElement.DrawFillProperty, ValueResetFlags.Local);
e.RowElement.ResetValue(LightVisualElement.GradientStyleProperty, ValueResetFlags.Local);
//e.RowElement.ResetValue(LightVisualElement.BackColorProperty, ValueResetFlags.Local);
e.RowElement.ResetStyleSettings(true, null);
//}
}
}
}
Thank you for writing.
Please note that the SetDefaultValueOverride override is working differently and it is not suitable to use it in this way in a formatting event. In order to use the theme value override API please upgrade to the latest version. This functionality was introduced in our 2015.3.930 release.
If that is not possible you can try performing a check in the formatting event and apply the custom colors only to the default state:
private
void
radGridView1_RowFormatting(
object
sender, Telerik.WinControls.UI.RowFormattingEventArgs e)
{
if
((
int
)e.RowElement.RowInfo.Cells[0].Value == 5 && e.RowElement.VisualState ==
"GridDataRowElement"
)
{
e.RowElement.DrawFill =
true
;
e.RowElement.GradientStyle = GradientStyles.Solid;
e.RowElement.BackColor = Color.LightGreen;
}
else
{
e.RowElement.ResetValue(LightVisualElement.DrawFillProperty, ValueResetFlags.Local);
e.RowElement.ResetValue(LightVisualElement.GradientStyleProperty, ValueResetFlags.Local);
e.RowElement.ResetValue(LightVisualElement.BackColorProperty, ValueResetFlags.Local);
}
}
I hope this information was useful. Should you have further questions please do not hesitate to write back.
Regards,
Hristo Merdjanov
Telerik by Progress
Thanks for the info. Unfortunately, that prevented the backcolor from being changed at all.
As an alternative, is there some way to set the order of precedence for multiple ConditionalFormattingObject's? For example;
Three objects are created; ConditionalFormattingObject1, ConditionalFormattingObject2 and ConditionalFormattingObject3. If ConditionalFormattingObject1 is used, is there a way to prevent ConditionalFormattingObject2 and ConditionalFormattingObject3 from being used?
Thanks for the info. Unfortunately, that prevents the backcolor from being changed at all.
As an alternative, is there some way to set the order of precedence for multiple ConditionalFormattingObject's? For example;
There are three ConditionalFormattingObject's created; ConditionalFormattingObject1, ConditionalFormattingObject2, ConditionalFormattingObject3. If ConditionalFormattingObject1 is used, is there a way to prevent ConditionalFormattingObject2 and ConditionalFormattingObject3 from being used?
Thank you for writing.
The conditional formatting objects are applied per column and each of them is evaluated according to the applied rule. In this respect, there is no order of precedence for multiple objects.
Regarding the last code snippet I sent you, it is working well with the control default theme. Please check the attached video. If it is possible you can send a code snippet showing the result on your end or open a support ticket and attach your project.
I hope this helps. Should you have further questions please do not hesitate to write back.
Regards,
Hristo Merdjanov
Telerik by Progress
I was able to get it to display the selected row correctly by simply including an 'else' clause after 'if (!e.RowElement.RowInfo.IsSelected) and set the selected row to the correct backcolor. I also forced the grid to invalidate in the SelectionChanged event handler. Not sure that was necessary, but it seems to work better.
private void grdWeekendAssistance_RowFormatting(object sender, RowFormattingEventArgs e)
{
if (!e.RowElement.RowInfo.IsSelected)
{
if ((int)e.RowElement.RowInfo.Cells["RelationshipFlag"].Value == 1)
{
e.RowElement.DrawFill = true;
e.RowElement.GradientStyle = GradientStyles.Solid;
e.RowElement.BackColor = Color.Red;
}
else if ((int)e.RowElement.RowInfo.Cells["LimitedAdvocacyFlag"].Value == 1)
{
e.RowElement.DrawFill = true;
e.RowElement.GradientStyle = GradientStyles.Solid;
e.RowElement.BackColor = Color.Orange;
}
else if ((int)e.RowElement.RowInfo.Cells["AssociateLanguageID"].Value == (int)Common.Lib.Language.Spanish)
{
e.RowElement.DrawFill = true;
e.RowElement.GradientStyle = GradientStyles.Solid;
e.RowElement.BackColor = Color.Green;
}
else if ((int)e.RowElement.RowInfo.Cells["CampaignSubTypeID"].Value != (int)Common.Lib.CampaignSubtype.WeekendAssignment &&
(int)e.RowElement.RowInfo.Cells["CampaignSubTypeID"].Value != (int)Common.Lib.CampaignSubtype.Salesians &&
(int)e.RowElement.RowInfo.Cells["CampaignSubTypeID"].Value != (int)Common.Lib.CampaignSubtype.PreciousBlood)
{
e.RowElement.DrawFill = true;
e.RowElement.GradientStyle = GradientStyles.Solid;
e.RowElement.BackColor = Color.LightBlue;
}
else if (e.RowElement.RowInfo.Cells["AssociateState"].Value.ToString() != e.RowElement.RowInfo.Cells["HLState"].Value.ToString())
{
e.RowElement.DrawFill = true;
e.RowElement.GradientStyle = GradientStyles.Solid;
e.RowElement.BackColor = Color.Yellow;
}
else
{
if (e.RowElement.IsOdd && !e.RowElement.IsSelected)
{
e.RowElement.DrawFill = true;
e.RowElement.GradientStyle = GradientStyles.Solid;
e.RowElement.BackColor = Color.Gainsboro;
}
else
{
e.RowElement.ResetValue(LightVisualElement.DrawFillProperty, ValueResetFlags.Local);
e.RowElement.ResetValue(LightVisualElement.GradientStyleProperty, ValueResetFlags.Local);
e.RowElement.ResetValue(LightVisualElement.BackColorProperty, ValueResetFlags.Local);
}
}
}
else
{
e.RowElement.DrawFill = true;
e.RowElement.GradientStyle = GradientStyles.Solid;
e.RowElement.BackColor = Color.DodgerBlue;
}
}
void grdWeekendAssistance_SelectionChanged(object sender, EventArgs e)
{
this.grdWeekendAssistance.Invalidate();
}
Thank you for writing back.
I am glad that you have managed to achieve a working solution in your actual project. The else clause is needed because of the virtualized visual elements. In other words, the visual cells are reused representing multiple logical elements. This is needed to improve the performance of the control:
- http://docs.telerik.com/devtools/winforms/gridview/fundamentals/ui-virtualization
- http://docs.telerik.com/devtools/winforms/gridview/fundamentals/logical-vs.-visual-grid-structure
Calling the Control.Invalidate method will send a paint message to the grid and since it is working well on your end you can go ahead with it.
I hope this helps. Should you have further questions please do not hesitate to write back.
Regards,
Hristo Merdjanov
Telerik by Progress