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

Please try the following approach:
<
Style
TargetType
=
"TextBox"
x:Key
=
"myTxtStyle"
BasedOn
=
"{StaticResource TextBoxStyle}"
>
<
Setter
Property
=
"MaxLength"
Value
=
"10"
/>
</
Style
>
Please update me if there are any issues.
Regards,
Stefan Nenchev
Telerik


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

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?

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.

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;
}
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

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;
}
};
}
}
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

Hello Dilyan,
Thanks for the confirmation and timely response.
Best,
Jan

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));
}
}
}