
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 namespace
namespace
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