This is a migrated thread and some comments may be shown as answers.

Assign Background Color of Cell

13 Answers 503 Views
Grid for XAML
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Robert
Top achievements
Rank 1
Robert asked on 17 Jul 2013, 11:36 PM
I am working with the RadDataGrid for Windows 8 on a proof of technology project;

The goal is to create a List programmatically in C#, and assign a background color to each cell programmatically in C# - based on the cell value;

Thanks in advance for any insight, guidance;

List<ProjectMetaData> lstProjectMetaData = new List<ProjectMetaData>()
          {
              new ProjectMetaData { AssemblyOne = "A" , AssemblyTwo = "B", AssemblyThree = "C" },
              new ProjectMetaData { AssemblyOne = "D", AssemblyTwo = "E", AssemblyThree = "F" },
              new ProjectMetaData { AssemblyOne = "G", AssemblyTwo = "H", AssemblyThree = "K" }            
          };
                      
          grdTest.ItemsSource = lstProjectMetaData;

public class ProjectMetaData
    {
        public string AssemblyOne { get; set; }
        public string AssemblyTwo { get; set; }
        public string AssemblyThree { get; set; }
    }

<Grid:RadDataGrid x:Name="grdTest" Width="600" Height="400" HorizontalAlignment="Center" VerticalAlignment="Center"/>

13 Answers, 1 is accepted

Sort by
0
Accepted
Ivaylo Gergov
Telerik team
answered on 18 Jul 2013, 03:39 PM
Hello Robert,

Thank you for your interest.

In order to change the background color of a cell depending on its value, you can use the DataGridColumn.CellDecorationStyleSelector property. The style of a cell should be of type Rectangle.
Note, you have two options to achieve this:
  1. To set the RadDataGrid.AutoGenerateColumns property to "False" and manually create each DataGridColumn instance and set its CellDecorationStyleSelector property.
  2. To override the GenerateColumn command that will allow you to plug before the columns have been generated and assign their CellDecorationStyleSelector property.
For your convenience, I have attached a project that shows the two scenarios(The code for the first scenario is commented and you will also need to change the AutoGenerateColumns property to false in order to test it).
More about the DataGrid commands can be found here - http://www.telerik.com/help/windows-8-xaml/datagrid-commands-overview.html.
Also, I would like to add that if you need to change another style settings of a cell depending on its value, you can use the  DataGridColumn.CellContentStyleSelector property.

I hope this information is useful. Let me know if I can assist you in some other way.

 

Regards,
Ivaylo Gergov
Telerik

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Robert
Top achievements
Rank 1
answered on 18 Jul 2013, 07:57 PM
Update: ToString() is necessary... also, null values have to checked;
else if ((item as DataGridCellInfo).Value.ToString() == "2")
            {
                return this.StyleA;
            }


Thank you for the feedback, and solution - works very well;

However, when changing the ItemSource of the RadDataGrid  to the results of a WCF Service Call in the form of an ObservableCollection - the number values are not getting assigned as colors;

In the first column of the ObservableCollection, which gets assigned to the ItemsSource of the RadDataGrid, the values are names of metrics;  the other columns each hold a number value;

Working with the below code, and going thru debug - I am able view the values 2, 0, -2;  however, the code is not dropping into the return this.StyleA, return this.StyleB, return this.StyleC;  this is occurring, even through the values are plainly 2, 0, -2;

thanks in advance for insight, guidance;
protected override Windows.UI.Xaml.Style SelectStyleCore(object item, Windows.UI.Xaml.DependencyObject container)
        {
            if ((item as DataGridCellInfo).Value == "2")
            {
                return this.StyleA;
            }
            else if ((item as DataGridCellInfo).Value == "0")
            {
                return this.StyleB;
            }
            else if ((item as DataGridCellInfo).Value == "-2")
            {
                return this.StyleC;
            }
            else return null;
        }
0
Robert
Top achievements
Rank 1
answered on 19 Jul 2013, 07:49 PM
An additional question regarding the assignment of a background color:  In our scenario it is necessary to hide the value of 2, 0, -2 in a cell;  On the one hand, the value has to be determined in the CustomCellDecoration Style Selector class for a background color to be assigned - utilizing RadDataGrid.Resources;  On the other hand, the actual value of 2, 0, -2 is be hidden and not displayed in the cell;                                   Thanks in advance for insight, guidance;
0
Accepted
Rosy Topchiyska
Telerik team
answered on 23 Jul 2013, 02:58 PM
Hello Robert,

Thank you for your question.

You can change the content style of a cell through the DataGridColumn.CellContentStyleSelector property (the style of a cell should be of type TextBlock). I have modified the project from the previous answer to demonstrate how to achieve this. For the Style of the cells that should be hidden I have set the color specifying the foreground of the TextBlock to have alpha transparency 0.

I hope this solution satisfies your needs.

Regards,
Rositsa Topchiyska
Telerik

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Robert
Top achievements
Rank 1
answered on 24 Jul 2013, 08:11 PM
Excellent - thank you very much;

One additional question;

The same cell that requires 2, -2, 0 to be evaluated, apply a style, and be hidden - has one additional requirement;

Is it possible to assign an actual number value to the same cell that hides 2, -2, 0 ?

I tied working with an additional CustomContentDecorationSelector to determine if one TextBlock can be hidden (for 2, -2, 0), and if a second TextBlock can be utilized in the same cell to accommodate an actual number value to be displayed - however, the attempted implementation was not successful; 

Thanks in advance for insight, guidance;
0
Accepted
Rosy Topchiyska
Telerik team
answered on 26 Jul 2013, 11:12 AM
Hello Robert,

For the scenario you described I suggest using DataGridTemplateColumn. I modified the example once again to demonstrate how this can be achieved. The DataTemplate of the DataGridTemplateColumn.CellContentTemplate has a Border element with TextBlock in it. The Text property of the TextBlock and the Background property of the Border are bound to a property of the model through value converters.

I hope this helps.

Regards,
Rositsa Topchiyska
Telerik

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Robert
Top achievements
Rank 1
answered on 26 Jul 2013, 05:52 PM
Thanks very much for the answers, sample solution - works perfect, if a DataGridTemplateColumn can be pre-defined in the RadDataGrid;

Can the same functionality be implemented without utilizing a DataGridTemplateColumn, and maintain the prior RadDataGrid which contains a  RadDataGrid.Resources section and a RadDataGrid.Command section - without supplying any pre-defined DataGridTextColumns;

In my scenario, a List is dynamically populated in C# - based on results from a call to an ASP.Net Web API; the number of columns changes, based on parameters such Date, Area, Segment - when calling into the ASP.Net Web API;  the ItemsSource of the RadDataGrid is bound once, but the List utilized for data binding may include one column, four columns, or ten columns - this information is not known until run time;

Commands within the RadDataGrid work well, as provided in the previous sample solution, to give background color and number values;  perhaps an additional command in the CustomGenerateColumnCommand C# file can route to the CellValueConverter, CellBackgroundConverter C# files to provide custom text and background color;

My scenario for the RadDataGrid seems rather challenging, and the continued feedback is appreciated;


0
Accepted
Rosy Topchiyska
Telerik team
answered on 29 Jul 2013, 04:13 PM
Hello Robert,

You can generate the DataGridTemplateColumn in the CustomGenerateColumnCommand - you can see how in the attached project. Please, note that the value converters have to be defined in the application resources (App.xaml) in order access them in the CustomGenerateColumnCommand class.

I hope this was useful and, please, let me know if I can help you in some other way.

Regards,
Rositsa Topchiyska
Telerik

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Robert
Top achievements
Rank 1
answered on 29 Jul 2013, 08:32 PM
Excellent - technical support from Telerik is the best!  Rositsa, thank you very much for the insight, and guidance;
0
Robert
Top achievements
Rank 1
answered on 20 Aug 2013, 02:38 PM
Update : I have implemented an additional command in the RadDataGrid.Commands section -

<local:CustomCellDoubleTapped/>


and a CustomCellDoubleTapped class (please see below code snippet);

I am writing to ask how best can the actual value of a double clicked (or tapped) cell be captured, programmatically in C#;

In debug mode, I am able to view the contents of the below context variable - but the navigation to the actual values is proving to be difficult;

Thanks in advance for insight, guidance;
 
class CustomCellDoubleTapped : DataGridCommand
    {
        string testTapEvent = string.Empty;
 
        public CustomCellDoubleTapped()
        {
            this.Id = CommandId.CellDoubleTap;
        }
 
        public override bool CanExecute(object parameter)
        {
            var context = parameter as DataGridCellInfo;
            
            // put your custom logic here
            return true;
        }
 
        public override void Execute(object parameter)
        {
            var context = parameter as DataGridCellInfo;
 
            testTapEvent = context.Value.ToString();
 
            // put your custom logic here
        }
 
    }


I am writing to ask how best two types of tasks can be accomplished if the DataGridTemplateColumn is generated in the CustomGenerateColumnCommand;

1) specify the HorizontalAlignment = "Center" for the Column headings of the RadDataGrid - if the DataGridTemplateColumn is generated in the CustomGenerateColumnCommand;

In the below code snippet, a HorizontalAlignment = 'Center' is added for the TextBlock - and this works as intended to center value of each TextBlock;  I am writing to determine if it is possible to center the column headings of RadDataGrid in a similar fashion;

2) add the functionality that if a user double clicks a given cell, an event can be handled in the C# code behind;

I am working with Telerik RadControls for Windows 8 - Version 2013.2.611.0
 
Thanks in advance for any insight;

Current Execute method, contained within CustomGenerateColumnCommand.cs -
public override void Execute(object parameter)
        {
            var context = parameter as GenerateColumnContext;
            var property = context.PropertyName;           
 
            var xaml = "<DataTemplate xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'><Border Background=\'{Binding " +
                       property +
                       ", Converter={StaticResource CellBackgroundConverter}}'><TextBlock HorizontalAlignment='Center' Text='{Binding " +
                       property +
                       ", Converter={StaticResource CellValueConverter}}' Margin='10'/></Border></DataTemplate>";
 
            var template = (DataTemplate)XamlReader.Load(xaml);
 
            context.Result = new DataGridTemplateColumn()
            {
                CellContentTemplate = template,
                Header = property                  
            };
 
        }

<telerikGrid:RadDataGrid x:Name="DataGrid" Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" Width="Auto" Height="Auto" HorizontalAlignment="Center" VerticalAlignment="Top" Visibility="Collapsed">
            
           <telerikGrid:RadDataGrid.Commands>
               <local:CustomGenerateColumnCommand/>
           </telerikGrid:RadDataGrid.Commands>
            
       </telerikGrid:RadDataGrid>

var xaml = "<DataTemplate xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'><Border Background=\'{Binding " +
                      property +
                      ", Converter={StaticResource CellBackgroundConverter}}'><TextBlock HorizontalAlignment='Center' Text='{Binding " +
                      property +
                      ", Converter={StaticResource CellValueConverter}}' Margin='10'/></Border></DataTemplate>";
0
Accepted
Ivaylo Gergov
Telerik team
answered on 21 Aug 2013, 11:34 AM
Hi Robert,

Directly on your questions:

First, in the scenario with template columns generation the DataGridCellInfo.Value for each cell (retrieved from the context parameter in the Execute(...) method) represents the corresponding business object as a whole. So, in order to get the value of the selected cell, you can use the DataGridColumn.Name property(which is unique) and store the name of the property of the business object that is bound to the column. Thus, you can manually get the value. I have modified the previously attached project to match this scenario.

About the header alignment - you can center the column headers through the DataGridColumn.HeaderStyle property. You need to apply a style that targets the DataGridColumnHeader (that is in the Telerik.UI.Xaml.Controls.Grid.Primitives namespace) and set the HorizontalContentAlignment to Center. This change is also included in the attached project.

About the third question - I am not quite sure what do you want to achieve as generally the command pattern (the CellDoubleTap command) should allow you to execute your custom logic as part of the command mechanism in the Execute(...) method -- could you please elaborate a bit more on the C# event request or give us an example?

Let me know if this helps.



Regards,
Ivaylo Gergov
Telerik

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Robert
Top achievements
Rank 1
answered on 21 Aug 2013, 06:03 PM

Update: the below line of C# resolves the issue:

var value = (context.Value as IDictionary<string, Object>);



Thank you for the feedback;

Implementing a Resources section, within the RadDataGrid, and setting the HeaderStyle = this.Owner.Resources["ColumnHeaderStyle"] as Style works excellent - and the Column Heading Names are now centered perfectly;

Is it possible to work with the SelectionChanged event of the RadDataGrid, or a different event, in the code-behind of the Xaml Page where the RadDataGrid resides to capture the values a selected cell?

In the Windows 8 application I am building out, rather than using a pre-defined class (such as ProjectMetaData in the sample solution), an ExpandoObject() as IDictionary<String, Object> is utilized to dynamically create a class - based on results from a call to an ASP.Net Web API, which communicates with an internal SQL Server database; 

An ObservableCollection<IDictionary<string, Object>> newListInstance is assigned to the RadDataGrid, after the ExpandoObject() instance is added to newListInstance during a looping process;  

In the CustomCellDoubleTapped.cs file, the dynamically created class cannot be accessed, and line of
var value = (context.Value as ProjectMetaData) can not be completed;

var context = parameter as DataGridCellInfo; - is OK;

The SelectionChanged event, or a different event, in the code-behind of the Xaml Page where the RadDataGrid resides would work OK -  the goal is to obtain the cell value of a clicked (or double clicked) cell;

Thanks in advance for insight, guidance;

<telerikGrid:RadDataGrid x:Name="DataGrid" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" Width="Auto" Height="Auto" SelectionUnit="Cell"
                                 HorizontalAlignment="Center" VerticalAlignment="Top" Visibility="Collapsed" Margin="20,20,20,0" SelectionChanged="DataGrid_SelectionChanged">
 
            <telerikGrid:RadDataGrid.Resources>
                <Style TargetType="gridPrimitives:DataGridColumnHeader" x:Key="ColumnHeaderStyle">
                    <Setter Property="HorizontalContentAlignment" Value="Center"/>
                </Style>
            </telerikGrid:RadDataGrid.Resources>
 
            <telerikGrid:RadDataGrid.Commands>
                <local:CustomGenerateColumnCommand/>
                <local:CustomCellDoubleTapped/>
            </telerikGrid:RadDataGrid.Commands>
             
        </telerikGrid:RadDataGrid>

ObservableCollection<IDictionary<string, Object>> newListInstance = new ObservableCollection<IDictionary<string, object>>();
   
 foreach (var child in jObj.Children())
                    {
                        var instance = new ExpandoObject() as IDictionary<string, Object>;
                                           
                        for (int j = 1; j < child.Count; j++)
                        {   
                            instance.Add(addColumnHeadings[j], (string)child[j]);                            
                        }
 
                        newListInstance.Add(instance);
}
 
 DataGrid.ItemsSource = newListInstance;
0
Accepted
Ivaylo Gergov
Telerik team
answered on 22 Aug 2013, 01:12 PM
Hello Robert,

Yes, it is possible to use the RadDataGrid.SelectionChanged event in order to get the selected item/s. This is possible through the RadDataGrid.SelectedItem or RadDataGrid.SelectedItems(in case of multiple selection mode). Depending on the selection unit(row or cell) the SelectedItem property hold a DataGridCellInfo object or the business object that is selected, respectively the SelectedItems property holds an ObservableCollection of DataGridCellInfo objects/ business objects. In the event handler you can also access the last added or removed object/s through the DataGridSelectionChangedEventArgs like this:
private void grdTest_SelectionChanged(object sender, Telerik.UI.Xaml.Controls.Grid.DataGridSelectionChangedEventArgs e)
{
    var addedItems = e.AddedItems; // IEnumerable<object>
    var removedItems = e.RemovedItems;  //IEnumerable<object>            
}

I hope this helps.


Regards,
Ivaylo Gergov
Telerik

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

Tags
Grid for XAML
Asked by
Robert
Top achievements
Rank 1
Answers by
Ivaylo Gergov
Telerik team
Robert
Top achievements
Rank 1
Rosy Topchiyska
Telerik team
Share this question
or