Hello,
I would like to be able to data bind to the GridViewCell.IsEnabled flag. The reason for this is I have a GridView where certain cells are editable or not based on the property value of the underlying object. Right now I data bind the IsReadOnly flag of the TextBox within the cell and while that prevents the user from changing data, the customer asked that the cell not even be a tab stop.
This Style works:
| <Style x:Key="EditableCellStyle" TargetType="gridView:GridViewCell"> |
| <Setter Property="IsEnabled" Value="True"/> |
| </Style> |
This style produces the following error when trying to load the page: AG_E_RUNTIME_MANAGED_UNKNOWN_ERROR
| <Style x:Key="EditableCellStyle" TargetType="gridView:GridViewCell"> |
| <Setter Property="IsEnabled" Value="{Binding MyIsEnabledFlag}"/> |
| </Style> |
Any work-around for the 2nd style? BTW, yes changing the flag in the RowLoaded event of the GridView works however, the grid I am using has to display a large amount of data and disabling virtualization makes performance very slow and enabling virtualization produces erratic results with doing this via RowLoaded.
Thanks for any suggestions.
Dan
19 Answers, 1 is accepted
You cannot use Binding for style setters in Silverlight. If you want to assign value conditionally you can use CellStyleSelector property of GridViewColumn - later Today we will upload our Q2 2010 SP2 and you will able to find lots of examples for style and template selectors.
Greetings,
Vlad
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
I would also like to easily bind to GridViewCell.IsEnabled. I see in your demos examples of using the CellStyleSelector and CellTemplate, but this all seems serious overkill for something I'm going to need to do a lot. I'm implementing MVVM and would ideally just like to bind to some property on my view model to control whether an individual cell is enabled or not. Can you please provide the simplest example to achieve this?
Thanks,
Terry
Your best bet would be to use CellStyleSelector, because even if you can somehow set a property on a GridViewCell, this will seriously affect virtualization and can break any number of things.
Best wishes,
Yavor Georgiev
the Telerik team
Thanks,
Terry
Please refer to this blog post, I think it will be more clarifying. Please let me know if you need additional help on the matter, and I'll be happy to prepare a sample solution for you.
Greetings,Yavor Georgiev
the Telerik team
1) I used a StyleSelector to set the cell's 'IsEnabled' property to false as needed. This works great except that I also need copy/paste functionality and need to set the 'SelectionUnit' property of the grid view to 'Cell'. Now, those cells that get disabled cannot even be selected, which I can understand, but I need them to be selectable. Plus, I'm not crazy about the disabled look of the cells - it really breaks up the consistency of the grid. Ideally, I just want the text to be gray, not the whole cell. I know I've got control over this in the style selector, but it doesn't play nice with my alternate row background color. So...a number of issues here.
2) I used a DataTemplateSelector to display a TextBlock instead of TextBox for the CellEditTemplateSelector. This gets me the look I desire, but the grid interaction is not clean. When I click on a "disabled" cell, it's obvious that the cell still technically goes into edit mode - the text shifts and the row header shows an editing icon, even though the user can't really edit anything with the TextBlock. But in this case, of course, I can at least select any and all cells for copy/paste.
Can you suggest any other approach for me? Ultimately, I just want a selectable, uneditable cell that looks clean. BTW, the column's IsReadOnly property seems to behave like I want, but I need it on a bindable per-cell basis.
Thanks,
Terry
Please provide us a solid solution as Terry requests. We too are seeking a solution and I am sure this will benefit numerous others.
Regards,
John Sherwin
Rimini Software
Please find attached a sample solution that accomplishes your goal. The mechanism is composed of a CellStyleSelector and two attached properties. Please let me know if there is anything else I can do to assists you in the matter.
Greetings,Yavor Georgiev
the Telerik team
I have customized 3 grids now to allow for making cells readonly. Anyway, I have extended Teleriks most recently and would be glad to share my solution as well. Its not as nice as it will be when Telerik implements the functionality *wink* *wink*, but my only problem with it is that it will not take you out of edit mode if you change the property while editing - it prevents you from going into edit mode.
*sigh* can't attach the sample - beware THE MAN.
make a new class, I named mine ReadOnlyGridViewColumns.cs
using System.Windows;using System.Windows.Data;//change namespacenamespace RadControlsSilverlightApp1{ public class GridViewCellAttached : DependencyObject { #region Attached Properties /// <summary> /// Bound property to attach to the cell /// </summary> public static readonly DependencyProperty IsCellReadOnlyProperty = DependencyProperty.RegisterAttached( "IsCellReadOnly", typeof(bool), typeof(GridViewDataColumn), null); public static void SetIsCellReadOnly(DependencyObject element, bool value) { element.SetValue(IsCellReadOnlyProperty, value); } public static bool GetIsCellReadOnly(DependencyObject element) { return (bool)element.GetValue(IsCellReadOnlyProperty); } #endregion } public interface IGridViewColumnBase { Binding IsCellReadOnlyBinding { get; set; } } public class GridViewCheckBoxColumn : Telerik.Windows.Controls.GridViewCheckBoxColumn, IGridViewColumnBase { /// <summary> /// To allow for defining the binding in XAML /// </summary> public Binding IsCellReadOnlyBinding { get; set; } } public class GridViewComboBoxColumn : Telerik.Windows.Controls.GridViewComboBoxColumn, IGridViewColumnBase { /// <summary> /// To allow for defining the binding in XAML /// </summary> public Binding IsCellReadOnlyBinding { get; set; } } public class GridViewDataColumn : Telerik.Windows.Controls.GridViewDataColumn, IGridViewColumnBase { /// <summary> /// To allow for defining the binding in XAML /// </summary> public Binding IsCellReadOnlyBinding { get; set; } } public class GridViewDynamicHyperlinkColumn : Telerik.Windows.Controls.GridViewDynamicHyperlinkColumn, IGridViewColumnBase { /// <summary> /// To allow for defining the binding in XAML /// </summary> public Binding IsCellReadOnlyBinding { get; set; } } public class GridViewHyperlinkColumn : Telerik.Windows.Controls.GridViewHyperlinkColumn, IGridViewColumnBase { /// <summary> /// To allow for defining the binding in XAML /// </summary> public Binding IsCellReadOnlyBinding { get; set; } } public class GridViewImageColumn : Telerik.Windows.Controls.GridViewImageColumn, IGridViewColumnBase { /// <summary> /// To allow for defining the binding in XAML /// </summary> public Binding IsCellReadOnlyBinding { get; set; } } public class GridViewMaskedTextBoxColumn : Telerik.Windows.Controls.GridViewMaskedTextBoxColumn, IGridViewColumnBase { /// <summary> /// To allow for defining the binding in XAML /// </summary> public Binding IsCellReadOnlyBinding { get; set; } }}In your MainPage.xaml.cs (or equiv) add this code to your radGridView_BeginningEdit (or attach one)
private void radGridView1_BeginningEdit(object sender, Telerik.Windows.Controls.GridViewBeginningEditRoutedEventArgs e){ //attach our property to the cell and set the binding //since the binding has no "Source" it will use the datacontext of the cell. If you WANT to use the datacontext of something else then plug it in here //if readonly is determined at the page level then just setting a column to readonly woudl suffice. If you want cell level readonly you should have a view model for each row //and a readonly property for each property...IMHO var column = e.Cell.Column as RadControlsSilverlightApp1.IGridViewColumnBase; if (column != null) { if (column.IsCellReadOnlyBinding != null) { if (e.Cell.GetBindingExpression(RadControlsSilverlightApp1.GridViewCellAttached.IsCellReadOnlyProperty) == null) { //if the binding is missing this is the first time we have edited this cell, so set the binding e.Cell.SetBinding(RadControlsSilverlightApp1.GridViewCellAttached.IsCellReadOnlyProperty, column.IsCellReadOnlyBinding); } } if ((bool)(e.Cell.GetValue(RadControlsSilverlightApp1.GridViewCellAttached.IsCellReadOnlyProperty))) { e.Cancel = true; } }}Make an alias in your MainPage.xaml, like xmlns:roc="clr-namespace:RadControlsSilverlightApp1" (make it match the namespace your put the columns in).
Now when you define columns you use your alias instead of Teleriks if you want the readonly option.
<telerik:RadGridView Name="radGridView1" VerticalAlignment="Top" HorizontalAlignment="Stretch" AutoGenerateColumns="False" BeginningEdit="radGridView1_BeginningEdit" ItemsSource="{Binding GridList}"> <telerik:RadGridView.Columns> <roc:GridViewDataColumn DataMemberBinding="{Binding Column1}" IsCellReadOnlyBinding="{Binding SomePropertyRO}"/> <telerik:GridViewDataColumn DataMemberBinding="{Binding Column2}" /> <telerik:GridViewDataColumn DataMemberBinding="{Binding Column3}" /> <telerik:GridViewDataColumn DataMemberBinding="{Binding Column4}" /> </telerik:RadGridView.Columns></telerik:RadGridView>Its simple. It works. Good fortune to you!
I can imagine a 'GridViewCell.IsReadOnly' property that could make a lot of this easier. Do you guys have plans for such a thing?
Thanks again,
Terry
P.S. @Tyree: Thanks for the suggestion. I tried Yavor's example first, and it got me what I want, so didn't try yours. But appreciate the effort.
We will definitely consider adding such a property, although we are pretty far ahead in the planning phase right now and I'm unable to commit to a certain date or a release. In the mean time, please let me know if any obstacles arise with the solution I have provided.
Sincerely yours,Yavor Georgiev
the Telerik team
Thanks,
Terry
To force the StyleSelector to re-select the style, you need to raise a PropertyChanged event for the property the second cell is bound to on your data item. The easiest way would be to do this in the setter of the property the first cell is bound to.
Greetings,
Yavor Georgiev
the Telerik team
Terry
Indeed, SelectStyle is not called in these circumstances. I have corrected the issue and it should appear in our next Internal Release. Sadly, this fix won't be available in our Service Pack, which should be available in a couple of days.
I have updated your Telerik points for discovering this problem.
Kind regards,
Yavor Georgiev
the Telerik team
Of course, a spot-on observation on your part. This is actually the new official way to make a GridViewCell read-only. Terry, you should probably consider the new IsReadOnlyBinding property of GridViewDataColumn and, if possible, switch to it instead of my custom solution.
Regards,
Yavor Georgiev
the Telerik team
Thanks,
Terry
Currently there are no plans to implement such a property. Perhaps in this case you should stick to your current setup.
Sincerely yours,
Yavor Georgiev
the Telerik team
