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

Best way to set MaxLength on GridViewDataColumn

14 Answers 1383 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Geoff Hardy
Top achievements
Rank 1
Geoff Hardy asked on 28 Sep 2010, 02:27 PM
The TextBox control has a useful property called MaxLength which limits how many characters you can enter in it.

There does not seem to be an obvious/simple way to do the same thing with a GridViewDataColumn.

The way I got this to work was:

<Controls:GridViewDataColumn DataMemberBinding="{Binding ProductCode,Mode=TwoWay}" Header="Product Code" Width="150">
  <Controls:GridViewDataColumn.CellEditTemplate>
    <DataTemplate>
      <TextBox Text="{Binding ProductCode,Mode=TwoWay}" MaxLength="50"/>
    </DataTemplate>
   </Controls:GridViewDataColumn.CellEditTemplate>
</Controls:GridViewDataColumn>

Is there a better/simpler/less verbose way of achieving this?

14 Answers, 1 is accepted

Sort by
0
Pavel Pavlov
Telerik team
answered on 28 Sep 2010, 02:34 PM
Hi Geoff Hardy,

This is a good way to achieve that  and there is no need to change it .

As an alternative however , you may use the EditorStyle property of the GridViewDataColumn.
You will need to set it to a style targeting TextBox, and having one setter - for the MaxLenght property.

Regards,
Pavel Pavlov
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
John
Top achievements
Rank 1
Iron
answered on 28 Jan 2016, 08:49 PM
When supplying the new style for EditorStyle, what must it be based on for implicit styling?The editor looks a bit different of the style is not based on anything.
1
Stefan Nenchev
Telerik team
answered on 01 Feb 2016, 11:36 AM
Hi John,

Please try the following approach:
<Style TargetType="TextBox" x:Key="myTxtStyle" BasedOn="{StaticResource TextBoxStyle}">
           <Setter Property="MaxLength" Value="10"/>
</Style>
I have tested it from my end and the MaxLenght property is applied correctly. The default view of the editor is kept as well.

Please update me if there are any issues.

Regards,
Stefan Nenchev
Telerik
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 Feedback Portal and vote to affect the priority of the items
0
John
Top achievements
Rank 1
Iron
answered on 03 Feb 2016, 04:30 PM
Thanks. That works.
0
Rob Ainscough
Top achievements
Rank 1
answered on 23 Aug 2016, 08:04 PM

So creating a new Style for every possible length restriction I may have is the solution?  Come on folks, that's not a solution.  Why didn't Telerik add MaxLength to GridViewDataColumn ... that's why pay for these controls.

Rob

0
Stefan Nenchev
Telerik team
answered on 24 Aug 2016, 12:10 PM
Hi Rob,

Having in mind that it is possible to apply an EditorStyle for the columns or edit the CellTemplate/CellEditTemplate, we have decided to not expose such property on a column level as the mentioned features provide the user with a much wider set of modifications to apply.  Furthermore, creating such style and assigning it to the different columns` EditorStyle should not take much effort as well. We will consider exposing such property if we notice a high demand from our customers.

Regards,
Stefan Nenchev
Telerik by Progress
Do you need help with upgrading your AJAX, WPF or WinForms project? Check the Telerik API Analyzer and share your thoughts.
0
Joel
Top achievements
Rank 1
answered on 05 Oct 2017, 06:27 PM

I am running into a similar issue using the RadGridView -> GridViewDataColumn.

I have a model with a defined property as follows:

[DataModelColumn("LENDER_BRANCH_CODE")]
[Required(ErrorMessage = "{0} is required.")]
[StringLength(3, ErrorMessage = "{0} has a maximum length of {3}.")]
[Display(Name = "Lender Branch Code")]
public string LenderBranchCode
{
     get { return _LenderBranchCode; }
     set
     {
          _LenderBranchCode = value;
          NotifyPropertyChanged();
     }
}

 

and the following XAML to show it in a view:

<telerik:GridViewDataColumn DataMemberBinding="{Binding LenderBranchCode, Converter={converters:IntFormatConverter}, ConverterParameter={StaticResource BranchFmt}}" Header="Lender Branch Number" />

 

BranchFmt = "D3"

 

All is fine as long as I know to obey the maximum string length of the field.  Not putting anything generates the error from the "Required" annotation.  Putting in non-number characters handled in the converter (set to null, which triggers the "Required" annotation.  

 

The "StringLength" annotation, however, never generates a validation error I just get a "FormatException".  Is there any way to fix that or do I need to find an alternative to enforce string length validation?

0
Joel
Top achievements
Rank 1
answered on 05 Oct 2017, 08:58 PM

Turns out, a colleague created the model and put the wrong number in the maximum length spot.  Should have been:

 [StringLength(3, ErrorMessage = "{0} has a maximum length of {1}.")]

The error I was getting was due to the "3" being basically an "Index Out of Range" error.  Everything works as intended now, with the data annotations providing the appropriate feedback.  Thanks.

0
Jan Paolo
Top achievements
Rank 1
answered on 27 Nov 2018, 09:28 PM

Is it possible to do this using attached property?

I tried doing but the GridViewDataColumn.EditorStyle is null.

private static void OnMaxLengthChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    var gridViewDataColumn = (GridViewDataColumn)d;
}
0
Dilyan Traykov
Telerik team
answered on 30 Nov 2018, 01:13 PM
Hello Jan Paolo,

You can create the following behavior to achieve the desired result:

public class MaxLengthBehavior
{
    private int length = 0;
    private GridViewBoundColumnBase column;
 
    public static int GetLength(DependencyObject obj)
    {
        return (int)obj.GetValue(LengthProperty);
    }
 
    public static void SetLength(DependencyObject obj, int value)
    {
        obj.SetValue(LengthProperty, value);
    }
     
    public static readonly DependencyProperty LengthProperty =
        DependencyProperty.RegisterAttached("Length", typeof(int), typeof(MaxLengthBehavior), new PropertyMetadata(0, OnLengthChanged));
 
    private static void OnLengthChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var column = d as GridViewBoundColumnBase;
        var length = (int)e.NewValue;
        var behavior = new MaxLengthBehavior(column, length);
        behavior.Attach();
    }
 
    public MaxLengthBehavior(GridViewBoundColumnBase column, int length)
    {
        this.length = length;
        this.column = column;
    }
 
    private void Attach()
    {
        var grid = this.column.DataControl;
        grid.PreparingCellForEdit += Grid_PreparingCellForEdit;
    }
 
    private void Grid_PreparingCellForEdit(object sender, GridViewPreparingCellForEditEventArgs e)
    {
        if (e.Column == this.column)
        {
            var textBox = e.EditingElement as TextBox;
            if (textBox != null)
            {
                textBox.MaxLength = this.length;
            }
        }
    }
}

You can then use it like so:

<telerik:GridViewDataColumn local:MaxLengthBehavior.Length="3" DataMemberBinding="{Binding Name}"/>

Please let me know whether this would work for you.

Regards,
Dilyan Traykov
Progress Telerik
Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
Jan Paolo
Top achievements
Rank 1
answered on 03 Dec 2018, 07:27 PM

Hello Dilyan,

Thanks for the solution. Is there a reason why an instance of MaxLengthBehavior should be created?

I did something like this and seems to work. Is there a caveat on doing it like this?

public class MaxLengthBehavior
{
    public static int GetLength(DependencyObject obj) =>
        (int)obj.GetValue(LengthProperty);
 
    public static void SetLength(DependencyObject obj, int value) =>
        obj.SetValue(LengthProperty, value);
 
    public static readonly DependencyProperty LengthProperty =
        DependencyProperty.RegisterAttached(
            "Length",
            typeof(int),
            typeof(MaxLengthBehavior),
            new PropertyMetadata(0, OnLengthChanged));
 
    private static void OnLengthChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var column = (GridViewBoundColumnBase)d;
        var length = (int)e.NewValue;
        column.DataControl.PreparingCellForEdit += (s, editEventArgs) =>
        {
            if (editEventArgs.Column == column
                && editEventArgs.EditingElement is TextBox textBox)
            {
                textBox.MaxLength = length;
            }
        };
    }
}

0
Dilyan Traykov
Telerik team
answered on 04 Dec 2018, 04:25 PM
Hello Jan,

I seem to have broken the KISS principle with the implementation from my last reply. In other words - no, there's no specific reason I implemented the behavior in this matter.

I see nothing wrong with the approach you've taken and you're free to use it if it works for you.

I'd also like to thank you for sharing your simplified solution with the community. If I can further assist you in any way, please let me know.

Regards,
Dilyan Traykov
Progress Telerik
Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
Jan Paolo
Top achievements
Rank 1
answered on 04 Dec 2018, 04:29 PM

Hello Dilyan,

Thanks for the confirmation and timely response.

Best,

Jan

0
John
Top achievements
Rank 1
Iron
answered on 12 Aug 2022, 07:41 PM

I've been wondering if using the hard-wired event with an anonymous method to boot would cause a memory leak in an app that requires a re-creation of the grid for whatever reason. I guess me being lazy and trying to avoid doing it with the EditorStyle everywhere(3-4 dozen places), I've created a hybrid behavior that would assign a setter to the EditorStyle or create a new one if it's missing:


   public class MaxLengthBehavior
    {
        public static readonly DependencyProperty LengthProperty =
            DependencyProperty.RegisterAttached(
                "Length",
                typeof(int),
                typeof(MaxLengthBehavior),
                new PropertyMetadata(0, OnLengthChanged));

        public static int GetLength(DependencyObject obj) =>
                    (int)obj.GetValue(LengthProperty);

        public static void SetLength(DependencyObject obj, int value) =>
            obj.SetValue(LengthProperty, value);

        private static void OnLengthChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var column = (GridViewDataColumn)d;
            var length = (int)e.NewValue;

            if (column == null || column.CellEditTemplate != null) return;

            if (column.EditorStyle == null)
            {
                var s = new Style() { BasedOn = Application.Current.Resources["TextBoxStyle"] as Style, TargetType = typeof(TextBox) };
                s.Setters.Add(new Setter(TextBox.MaxLengthProperty, length));
                column.EditorStyle = s;
            }
            else
            {
                var s = column.EditorStyle;
                var setter = s.Setters.OfType<Setter>().FirstOrDefault(s => s.Property == TextBox.MaxLengthProperty);
                s.Setters.Remove(setter);
                s.Setters.Add(new Setter(TextBox.MaxLengthProperty, length));
            }
        }
    }

Tags
GridView
Asked by
Geoff Hardy
Top achievements
Rank 1
Answers by
Pavel Pavlov
Telerik team
John
Top achievements
Rank 1
Iron
Stefan Nenchev
Telerik team
Rob Ainscough
Top achievements
Rank 1
Joel
Top achievements
Rank 1
Jan Paolo
Top achievements
Rank 1
Dilyan Traykov
Telerik team
Share this question
or