This question is locked. New answers and comments are not allowed.
Folks,
I want to dynamically change the look/style of the display of all cells in a given column at run time...I see easily how to do this by changing the template, via CellStyle etc. in the XAML, but I want to create these at runtime, essentially depending on the datatype being retrieved. For example, I may want a checkbox to show if a column type is boolean, or an image to show if it's an image.
I have messed with the Style() and Setters() etc. but can't really get anything to work.
Thoughts?
I want to dynamically change the look/style of the display of all cells in a given column at run time...I see easily how to do this by changing the template, via CellStyle etc. in the XAML, but I want to create these at runtime, essentially depending on the datatype being retrieved. For example, I may want a checkbox to show if a column type is boolean, or an image to show if it's an image.
I have messed with the Style() and Setters() etc. but can't really get anything to work.
Thoughts?
6 Answers, 1 is accepted
0
Scott
Top achievements
Rank 1
answered on 01 Sep 2009, 04:04 PM
Does anyone have anything on this? I'm desperate for a reasonable solution to create columns with controls in them (or dynamiucally created templates with Setter() etc.) based on datatypes. This used to be fairly straightforward using a Controls/Children.Add scenario, but can't for the life of me figure out how to do this at runtime, as opposed to statically in the xaml.
Help! Thoughts?
Help! Thoughts?
0
Accepted
Hello Scott,
If you are only trying to change the editor of your cells you can use the CellTemplate property instead of CellStyle since creating a CellTemplate requires less effort.
No matter if you are using CellTemplate or CellStyle you can define all possible styles and templates in the resource section of your XAML file:
Once you have all templates and styles you simply have to choose which one to load in you code-behind:
All the best,
Milan
the Telerik team
Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
If you are only trying to change the editor of your cells you can use the CellTemplate property instead of CellStyle since creating a CellTemplate requires less effort.
No matter if you are using CellTemplate or CellStyle you can define all possible styles and templates in the resource section of your XAML file:
| <UserControl.Resources> |
| <DataTemplate x:Key="FirstTemplate"> |
| <CheckBox IsChecked="{Binding Path=MyBoolProperty}"/> |
| </DataTemplate> |
| <DataTemplate x:Key="SecondTemplate"> |
| <TextBox Text="{Binding Path=MyTextProperty}"/> |
| </DataTemplate> |
| </UserControl.Resources> |
Once you have all templates and styles you simply have to choose which one to load in you code-behind:
| private void Button_Click(object sender, RoutedEventArgs e) |
| { |
| var column = this.gridvView.Columns[0] as GridViewDataColumn; |
| if(something) |
| column.CellTemplate = (Style)this.Resources["FirstTemplate"]; |
| else |
| column.CellTemplate = (Style)this.Resources["SecondTemplate"]; |
| this.gridvView.Rebind(); |
| } |
All the best,
Milan
the Telerik team
Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
0
Scott
Top achievements
Rank 1
answered on 03 Sep 2009, 04:05 PM
Milan,
When I use your code it forces me to use (DataTemplate) instead of (Style) on the cast, but otherwise excellent, thank you.
When I use your code it forces me to use (DataTemplate) instead of (Style) on the cast, but otherwise excellent, thank you.
0
Inquisitor Jax
Top achievements
Rank 1
answered on 04 Sep 2009, 06:50 AM
Scott,
I'm not sure if this is what you're after, but I have a similar post here
Basically, it's an extension method that takes in a type and uses reflection to loop through the properties of that type, and then
generate a column for each property.
The method can also be extended with a list of column overrides, and a list of properties to exclude from column generation.
I'm not sure if this is what you're after, but I have a similar post here
Basically, it's an extension method that takes in a type and uses reflection to loop through the properties of that type, and then
generate a column for each property.
The method can also be extended with a list of column overrides, and a list of properties to exclude from column generation.
0
Scott
Top achievements
Rank 1
answered on 04 Sep 2009, 01:08 PM
Inquisitor,
I think what you have is great if I want to iterate through rows, but because of the huge amount of data and the way I'm using the DataPager, I really need to use ItemsSource and let it bind. Right now I'm setting the CellTemplate in the _DataLoaded event, and everything works fine, but ONLY when I 'hardcode' the Binding Path (from my data source) into the template, like this:
<UserControl.Resources>
<DataTemplate x:Key="BooleanTemplate">
<CheckBox HorizontalAlignment="Center" IsChecked="{Binding Path=Column4}"/>
</DataTemplate>
</UserControl.Resources>
Any methods I use to set the Binding on IsChecked programatically results in all CheckBoxes being false or empty. Of course the goal is that I can "pass" a template name for the CellTemplate and Path for the Binding dynamically as logic determines.
Make sense? Thoughts?
I think what you have is great if I want to iterate through rows, but because of the huge amount of data and the way I'm using the DataPager, I really need to use ItemsSource and let it bind. Right now I'm setting the CellTemplate in the _DataLoaded event, and everything works fine, but ONLY when I 'hardcode' the Binding Path (from my data source) into the template, like this:
<UserControl.Resources>
<DataTemplate x:Key="BooleanTemplate">
<CheckBox HorizontalAlignment="Center" IsChecked="{Binding Path=Column4}"/>
</DataTemplate>
</UserControl.Resources>
Any methods I use to set the Binding on IsChecked programatically results in all CheckBoxes being false or empty. Of course the goal is that I can "pass" a template name for the CellTemplate and Path for the Binding dynamically as logic determines.
Make sense? Thoughts?
0
Hi Scott,
Ok, we might need to try another approach.
Let's define one very simple DataTemplate that will be used by all columns that should have dynamically set content:
The trick here is the Loaded event - it will allow us to determine when a cell is loaded and to change its content dynamically.
Once the template is in place you just have to assign it to the columns that will have dynamic content.
The logic that controls what content gets loaded is in the ContentControl_Loaded event handler:
In this handler you are free to create any kind of element and choose the binding machanism
I have attached a sample project that demonstreates this approach.
Hope it works.
Best wishes,
Milan
the Telerik team
Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
Ok, we might need to try another approach.
Let's define one very simple DataTemplate that will be used by all columns that should have dynamically set content:
| <DataTemplate x:Key="RuntimeContentTemplate"> |
| <ContentControl Loaded="ContentControl_Loaded"/> |
| </DataTemplate> |
The trick here is the Loaded event - it will allow us to determine when a cell is loaded and to change its content dynamically.
Once the template is in place you just have to assign it to the columns that will have dynamic content.
The logic that controls what content gets loaded is in the ContentControl_Loaded event handler:
| private void ContentControl_Loaded(object sender, RoutedEventArgs e) |
| { |
| var contentControl = (ContentControl)sender; |
| var parentCell = contentControl.ParentOfType<GridViewCell>(); |
| var column = parentCell.Column as GridViewDataColumn; |
| if (column.DataType == typeof(string)) |
| { |
| contentControl.Content = new TextBlock() { Text = "Text" }; |
| } |
| if (column.DataType == typeof(Position)) |
| { |
| TextBlock block = new TextBlock(); |
| Binding binding = new Binding("Position"); |
| binding.Mode = BindingMode.OneTime; |
| block.SetBinding(TextBlock.TextProperty, binding); |
| contentControl.Content = block; |
| } |
| if (column.DataType == typeof(int)) |
| { |
| TextBox box = new TextBox(); |
| Binding binding = new Binding("Number"); |
| binding.Mode = BindingMode.TwoWay; |
| box.SetBinding(TextBox.TextProperty, binding); |
| contentControl.Content = box; |
| } |
| } |
In this handler you are free to create any kind of element and choose the binding machanism
I have attached a sample project that demonstreates this approach.
Hope it works.
Best wishes,
Milan
the Telerik team
Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.