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

[Solved] Urgent Request : How to restrict character length in radgrid auto generated column

13 Answers 461 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.
Shiva
Top achievements
Rank 1
Shiva asked on 08 Dec 2010, 01:00 PM
Hi,

We have a telerik silverlight rad grid and columns are generated at runtime in that grid. We are using MVVM pattern and thus code is written in the viewmodel and NOT in the view.xaml.

We want to impose character limit for that column but are unable to do so because GridViewColumn does not have any maxlength kind of property. One alternate is using a cell template for that column and having a textbox in that template. Since textbox has maxlength property, we can set it to acheive the purpose but we faced few issues in this approach:

1.    Static resource (having a textbox) will be defined in the view.xaml. How will we access it on viewmodel.xaml?

Or any other suggestion is much appreciated around cracking this problem.

Regards,
Shiva

13 Answers, 1 is accepted

Sort by
0
Vlad
Telerik team
answered on 08 Dec 2010, 01:06 PM
Hi Shiva,

 You can use AutoGeneratingColumn event to access auto-generated columns and assign for this particular column custom CellTemplate where you can declare desired control and set desired properties. Other possible approach is to use DataAnnotations attributes to separate this logic in your data model. 

Greetings,
Vlad
the Telerik team
Browse the videos here>> to help you get started with RadControls for Silverlight
0
Shiva
Top achievements
Rank 1
answered on 08 Dec 2010, 01:16 PM
Hi Vlad,

We are autogenerating the columns using the silverlight data table concept coined by you in one of the blogs I found on web.

I just tried the above mentioned solution using auto generating columns event but no help.

The event does get fire but the Grid.Columns.Count is ZERO and thus cannot access the autogenerated columns.

Can you please provide a sample code snippet or elaborate a bit more on it??

Warm Regards,
Shiva
0
Vlad
Telerik team
answered on 08 Dec 2010, 01:27 PM
Hi Shiva,

 You can use e.Column in this event to access current column. 

All the best,
Vlad
the Telerik team
Browse the videos here>> to help you get started with RadControls for Silverlight
0
Shiva
Top achievements
Rank 1
answered on 08 Dec 2010, 01:59 PM
Dear Vlad,

Many thanks for your response. I tried your suggestion and it does work but this has cropped up another issue.

As I have mentioned in my previous blog, I'm using silverlight data table to bind my grid. As soon as I add the cell template in a cell, the data it contains vanishes.

Here are the steps I'm following:

viewmodel.xaml

foreach (DataElementSourceDestinationMapping objMapping in dataElementSourceDestination)
{
    DataRow row = new DataRow();
    row["DataElementID"] = objMapping.DataElementID;
    row["DataElementName"] = objMapping.DataElementName;
    foreach (SourceDestinationTable objTable in objMapping.SourceDestinationTableList)
    {
        row[objTable.TableName + "ID"] = objTable.TableID;
        row[objTable.TableName] = objTable.ColumnName;
        row[objTable.TableName + " IsActive"] = objTable.IsActive;
    }
    dtDESourceDest.Rows.Add(row);
}
DESourceDestTable = dtDESourceDest.ToList();

where:
dataElementSourceDestination:- is my data entity list

dtDESourceDest:- is the silverlight data table (from your blog post).

DESourceDestTable:- is the IList. This is the data source of my grid

Steps of execution

1.    As soon as DESourceDestTable = dtDESourceDest.ToList(); is executed, the grid is updated with the data from the entity list and AutoGeneratingColumn event of the grid in view.xaml gets executed.

2.    Code of view.xaml:
private void gridDESourceDest_AutoGeneratingColumn(object sender, GridViewAutoGeneratingColumnEventArgs e)
        {
            if (e.Column.Header.ToString() != "DataElementName" && (!e.Column.Header.ToString().Contains("ID")) && (!e.Column.Header.ToString().Contains("Active")))
            {
                e.Column.CellTemplate = (DataTemplate)Resources["TextBoxTemplate"];
            }         
        }

3.    Once the above event is executed, the cells gets the desired textboxes in them but the data they had in them is lost. Probably because they were hidden by the textboxes.

Is there any way to get the data in the textboxes or any better solution you can suggest me here?

Please share your comments/thoughts.

Warm Regards,
Shiva
0
Accepted
Vlad
Telerik team
answered on 08 Dec 2010, 02:10 PM
Hi Shiva,

How you've bound the controls in this template? You may need to have separate templates for different columns or you can use the approach demonstrated in this blog post (CellValueBindingBehavior) or you can create completely custom column and replace the auto-generated column using again e.Column. For example:

e.Column = new MyCustomColumn();

For more info about custom columns you can check this blog post

Kind regards,
Vlad
the Telerik team
Browse the videos here>> to help you get started with RadControls for Silverlight
0
Shiva
Top achievements
Rank 1
answered on 08 Dec 2010, 03:37 PM
Dear Vlad,

I checked your blog post around creating custom column controls. Everything is working fine except the fact that I'm getting this.DataMemebrBinding as NULL and that is why column is coming up as blank.

I have created the TextBoxColumn class like this:
public class TextBoxColumn : GridViewDataColumn
    {
        public override FrameworkElement CreateCellElement(GridViewCell cell, object dataItem)
        {
            var bar = cell.Content as TextBox;
  
            if (bar == null)
            {
                bar = new TextBox();
                bar.MaxLength = 20;
                bar.SetValue(TextBox.TextProperty, this.DataMemberBinding);
                cell.Content = bar;
            }
  
            return bar;
        }
  
        public override FrameworkElement CreateCellEditElement(GridViewCell cell, object dataItem)
        {
            var slider = new TextBox();
            slider.MaxLength = 20;
            slider.SetBinding(TextBox.TextProperty, this.DataMemberBinding);
            return slider;
        }
    }

and I'm associating this class at runtime in AutoGenerating event as mentioned below:

private void gridDESourceDest_AutoGeneratingColumn(object sender, GridViewAutoGeneratingColumnEventArgs e)
        {
            if (e.Column.Header.ToString() != "DataElementName" && (!e.Column.Header.ToString().Contains("ID")) && (!e.Column.Header.ToString().Contains("Active")))
            {
                                e.Column = TextBoxColumn();
            }
        }

The only reason I could see in your sample code and mine is that you have set autogenerated columns to false while in my case it is true. Below is my radgrid xaml code.

<telerik:RadGridView x:Name="gridDESourceDest" AutoGenerateColumns="True" ItemsSource="{Binding DESourceDestTable, Mode=TwoWay}" ValidatesOnDataErrors="None" ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Auto"
                                         Grid.Row="0" Grid.Column="0" CanUserDeleteRows="False" CanUserInsertRows="False" Visibility="{Binding IsGridVisible, Mode=TwoWay}" ShowGroupPanel="False" FrozenColumnCount="5" AutoGeneratingColumn="gridDESourceDest_AutoGeneratingColumn">
                    </telerik:RadGridView>

Another issue with this approach is that I'm loosing the header text using this approach. Here is the code I'm using in viewmodel.xaml to create columns and adding data in the row (a portion of the code was already provided in my previous reply).

DataTable dtDESourceDest = new DataTable();
            dtDESourceDest.Columns.Add(new DataColumn() { ColumnName = "DataElementID", DataType = typeof(int) });
            dtDESourceDest.Columns.Add(new DataColumn() { ColumnName = "DataElementName", DataType = typeof(string) });
  
            foreach (DataElementSourceDestinationMapping objMapping in dataElementSourceDestination)
            {
                foreach (SourceDestinationTable objTable in objMapping.SourceDestinationTableList)
                {
                    dtDESourceDest.Columns.Add(new DataColumn() { ColumnName = objTable.TableName + "ID", DataType = typeof(int) });
                    dtDESourceDest.Columns.Add(new DataColumn() { ColumnName = objTable.TableName, DataType = typeof(string) });
                    dtDESourceDest.Columns.Add(new DataColumn() { ColumnName = objTable.TableName + " IsActive", DataType = typeof(bool?) });
                }
                break;
            }
  
            foreach (DataElementSourceDestinationMapping objMapping in dataElementSourceDestination)
            {
                DataRow row = new DataRow();
                row["DataElementID"] = objMapping.DataElementID;
                row["DataElementName"] = objMapping.DataElementName;
  
                foreach (SourceDestinationTable objTable in objMapping.SourceDestinationTableList)
                {
                    row[objTable.TableName + "ID"] = objTable.TableID;
                    row[objTable.TableName] = objTable.ColumnName;
                    row[objTable.TableName + " IsActive"] = objTable.IsActive;
                }
  
                dtDESourceDest.Rows.Add(row);
            }
            DESourceDestTable = dtDESourceDest.ToList();

where:
dataElementSourceDestination:- is my data entity list

dtDESourceDest:- is the silverlight data table (from your blog post).

DESourceDestTable:- is the IList. This is the data source of my grid

Can you please urgently share your comments on this??

Your cooperation so far is highly appreciated.

Best Regards,
Shiva
0
Vlad
Telerik team
answered on 08 Dec 2010, 03:47 PM
Hello,

 You can copy the DataMemebrBinding from the original column to your custom column. 

Regards,
Vlad
the Telerik team
Browse the videos here>> to help you get started with RadControls for Silverlight
0
Shiva
Top achievements
Rank 1
answered on 08 Dec 2010, 03:50 PM
Dear Vlad,

Can you please give me a code snippet around this??

Best Regards,
Shiva
0
Vlad
Telerik team
answered on 08 Dec 2010, 03:52 PM
Hi,

Here is an example:

 e.Column = new TextBoxColumn() { DataMemebrBinding = ((GridViewDataColumn)e.Column).DataMemebrBinding };

Best wishes,
Vlad
the Telerik team
Browse the videos here>> to help you get started with RadControls for Silverlight
0
Shiva
Top achievements
Rank 1
answered on 08 Dec 2010, 03:58 PM
Dear Vlad,

Sorry for quizzing you again.

When I type the code as suggested by you, I get following two errors:

1.    RCMOperationsWidget.MDS.Models.TextBoxColumn' does not contain a definition for 'DataMemebrBinding'.
2.    Telerik.Windows.Controls.GridViewDataColumn' does not contain a definition for 'DataMemebrBinding' and no extension method 'DataMemebrBinding' accepting a first argument of type 'Telerik.Windows.Controls.GridViewDataColumn' could be found (are you missing a using directive or an assembly reference?

May I please have your comments on this. I'm sure that this time we will resolve it.

Best Regards,
Shiva
0
Shiva
Top achievements
Rank 1
answered on 08 Dec 2010, 04:02 PM
Sorry... my fault. I misspelled DataMemberBinding to DataMemebrBinding. That error has gone now but I'm getting different error this time at runtime at following line of TextBoxClass

bar.SetValue(

 

TextBox.TextProperty, this.DataMemberBinding);

 


The error says:

DependencyProperty of type System.String cannot be set on an object of type System.Windows.Data.Binding.


Suggestions???

Regards,
Shiva
0
Shiva
Top achievements
Rank 1
answered on 08 Dec 2010, 04:27 PM

Dear Vlad,

Another update for you...

I tried this code.....

bar.SetValue(TextBox.TextProperty, Convert.ToString(this.DataMemberBinding));

Using Convert.ToString(this.DataMemberBinding) kills the error I was getting but in the data grid cells I'm getting System.Windows.Data.Binding instead of actual data.

Can you please assist me on this? This is the last leg of this issue I guess so kindly share your comments with us on this.

Best Regards,
Shiva
0
Shiva
Top achievements
Rank 1
answered on 08 Dec 2010, 04:56 PM
Dear Vlad,

The problem has been resolved now. This is the final code of CreateCellElement function of TextBoxColumn class.

public override FrameworkElement CreateCellElement(GridViewCell cell, object dataItem)
        {
            var bar = cell.Content as TextBox;
  
            if (bar == null)
            {
                bar = new TextBox();
                bar.MaxLength = 20;
                bar.SetValue(TextBox.TextProperty, Convert.ToString(this.DataMemberBinding));
  
                Binding bind = new Binding(this.DataMemberBinding.Path.Path.ToString());
                bind.Mode = BindingMode.TwoWay;
                bar.SetBinding(TextBox.TextProperty, bind);
  
                cell.Content = bar;
            }
  
            return bar;
        }

In addition to SetValue function, I overwrote the SetBinding function as well. That did the trick.

Once again, thank so very much for your cooperation.

Cheers,
Shiva
Tags
GridView
Asked by
Shiva
Top achievements
Rank 1
Answers by
Vlad
Telerik team
Shiva
Top achievements
Rank 1
Share this question
or