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.