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
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:
- To set the RadDataGrid.AutoGenerateColumns property to "False" and manually create each DataGridColumn instance and set its CellDecorationStyleSelector property.
- To override the GenerateColumn command that will allow you to plug before the columns have been generated and assign their CellDecorationStyleSelector property.
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.
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; }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.
Rositsa Topchiyska
Telerik
Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.
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;
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.
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;
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.
<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>";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.
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;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.
Ivaylo Gergov
Telerik
Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.