This is a migrated thread and some comments may be shown as answers.

How to data bind to GridViewCell.IsEnabled?

19 Answers 954 Views
GridView
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Dan Kinchen
Top achievements
Rank 1
Dan Kinchen asked on 01 Jun 2010, 02:11 PM

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

Sort by
0
Vlad
Telerik team
answered on 01 Jun 2010, 02:15 PM
Hi Dan,

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.
0
Terry Foster
Top achievements
Rank 1
answered on 23 Jul 2010, 12:59 PM
Hi,

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
0
Yavor Georgiev
Telerik team
answered on 24 Jul 2010, 02:54 PM
Hi Terry Foster,

 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
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
0
Terry Foster
Top achievements
Rank 1
answered on 30 Jul 2010, 01:59 PM
So I'm looking at the examples of style and template selectors and am still at a loss as to how to disable a cell.  I see references to a 'UnitPriceConverter', 'ConditionalDataTemplateSelector', and 'ConditionStyleSelector', which all seem to be in an 'Example' namespace.  I don't see any code for these guys.  Should I be expected to know what they do and how to mimic their behavior?  Maybe I'm supposed to download the example to get more of the details, but I don't see an option to download any of the online examples.  I'm really confused - please help.  Ideally, if you could provide an example that does exactly what I'm wanting (i.e. conditionally disable a cell), I'd really appreciate it.

Thanks,
Terry
0
Yavor Georgiev
Telerik team
answered on 30 Jul 2010, 02:12 PM
Hi Terry Foster,

 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
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
0
Terry Foster
Top achievements
Rank 1
answered on 06 Aug 2010, 09:34 PM
Okay, I've tried two approaches to make cell's uneditable, neither of which quite gets me what I need.

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
0
John Sherwin
Top achievements
Rank 1
answered on 08 Aug 2010, 07:26 AM
Telerik:

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
0
Yavor Georgiev
Telerik team
answered on 11 Aug 2010, 03:23 PM
Hi John Sherwin,

 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
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
0
Tyree
Top achievements
Rank 2
answered on 11 Aug 2010, 07:14 PM
May I present an option? I couldn't find any rules stating we couldn't...

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!
0
Terry Foster
Top achievements
Rank 1
answered on 11 Aug 2010, 09:42 PM
Thanks, Yavor!  This finally gets me exactly what I want.

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.
0
Yavor Georgiev
Telerik team
answered on 12 Aug 2010, 09:30 AM
Hello Terry Foster,

 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
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
0
Terry Foster
Top achievements
Rank 1
answered on 23 Sep 2010, 02:52 PM
OK, I'm having one small 'obstacle' with this now.  I have a cell that is read-only based of the value of another cell.  When the second cell is changed, the first cell does not update its read-only state.  In essence, I believe the first cell just needs to have its style re-selected by the CellStyleSelector.  I have no ideas on how to do this. This is also pretty crucial to our application, so any help would greatly appreciated.

Thanks,
Terry
0
Yavor Georgiev
Telerik team
answered on 23 Sep 2010, 02:55 PM
Hi Terry Foster,

 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
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
0
Terry Foster
Top achievements
Rank 1
answered on 23 Sep 2010, 03:05 PM
I was hoping it would be as easy as that (because I'm already doing it), but it doesn't seem to work - my style selector code is not executed again.  I'm using internal build 2010.2.827.1040.

Terry
0
Yavor Georgiev
Telerik team
answered on 23 Sep 2010, 03:43 PM
Hello Terry Foster,

 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
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
0
Tyree
Top achievements
Rank 2
answered on 23 Sep 2010, 04:52 PM
Or you could use the IsReadOnlyBinding property on the columns available in the internal build and eliminate the need for the style selector.?
0
Yavor Georgiev
Telerik team
answered on 23 Sep 2010, 04:59 PM
Hello Tyree,

 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
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
0
Terry Foster
Top achievements
Rank 1
answered on 23 Sep 2010, 05:17 PM
Hmmm, not seeing it - I assume it is really new.  If it is what it sounds like it is, I will greatly welcome it.  However, I'll probably still want to apply my own styles (e.g., gray text) to a read-only cell.  Is there (will there be) a ReadOnlyStyle, or some such, property on the column as well?

Thanks,
Terry
0
Yavor Georgiev
Telerik team
answered on 23 Sep 2010, 05:24 PM
Hello Terry Foster,

 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
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
Tags
GridView
Asked by
Dan Kinchen
Top achievements
Rank 1
Answers by
Vlad
Telerik team
Terry Foster
Top achievements
Rank 1
Yavor Georgiev
Telerik team
John Sherwin
Top achievements
Rank 1
Tyree
Top achievements
Rank 2
Share this question
or