wpfwpftoolkitwpfdatagridmaxlengthdatagridtextcolumn

DataGridTextColumn.MaxLength?


How do I set the MaxLength property of the DataGridTextColumn?


Solution

  • <tk:DataGridTextColumn Binding="{Binding Text}">
        <tk:DataGridTextColumn.EditingElementStyle>
            <Style TargetType="TextBox">
                <Setter Property="MaxLength" Value="16"/>
            </Style>
        </tk:DataGridTextColumn.EditingElementStyle>
    </tk:DataGridTextColumn>
    

    You could also set it using the following behavior so you don't have to use a style and setters each time:

    Public Class TextBoxBehavior
        Private Shared Types As Type() = New Type() {GetType(AutoCompleteBox), GetType(ComboBox), GetType(DataGridTextColumn)}
    
        Public Shared Function GetMaxLength(ByVal element As DependencyObject) As Integer
            Return element.GetValue(MaxLengthProperty)
        End Function
    
        Public Shared Sub SetMaxLength(ByVal element As DependencyObject, ByVal value As Integer)
            element.SetValue(MaxLengthProperty, value)
        End Sub
    
        Private Shared Sub ValidateElement(ByVal element As DependencyObject)
            If element Is Nothing Then Throw New ArgumentNullException("element")
            If Not Types.Contains(element.GetType) Then Throw New NotSupportedException("The TextBoxBehavior is not supported for the given element")
        End Sub
    
        Public Shared ReadOnly MaxLengthProperty As DependencyProperty = 
         DependencyProperty.RegisterAttached("MaxLength", 
                            GetType(Integer), GetType(TextBoxBehavior), 
                            New FrameworkPropertyMetadata(Integer.MaxValue, AddressOf TextBox_MaxLengthChanged))
    
        Private Shared Sub TextBox_MaxLengthChanged(ByVal sender As Object, ByVal e As DependencyPropertyChangedEventArgs)
            If sender Is Nothing Then Exit Sub
    
            Dim value = DirectCast(e.NewValue, Integer)
    
            If TypeOf sender Is AutoCompleteBox Then
                Dim acb = DirectCast(sender, AutoCompleteBox)
    
                If acb.IsLoaded Then
                    Dim tb = DirectCast(acb.Template.FindName("Text", acb), TextBox)
                    tb.MaxLength = value
                Else
                    acb.AddHandler(AutoCompleteBox.LoadedEvent, New RoutedEventHandler(AddressOf Element_Loaded))
                End If
            ElseIf TypeOf sender Is ComboBox Then
                Dim cb = DirectCast(sender, ComboBox)
                If cb.IsLoaded Then
                    Dim tb = DirectCast(cb.Template.FindName("PART_EditableTextBox", cb), TextBox)
                    tb.MaxLength = value
                Else
                    cb.AddHandler(ComboBox.LoadedEvent, New RoutedEventHandler(AddressOf Element_Loaded))
                End If
            ElseIf TypeOf sender Is DataGridTextColumn Then
                Dim dgtc = DirectCast(sender, DataGridTextColumn)
    
                Dim setter = GetIsMaxLengthSet(dgtc.EditingElementStyle)
                If setter Is Nothing Then
                    Dim style = New Style(GetType(TextBox), dgtc.EditingElementStyle)
                    style.Setters.Add(New Setter(TextBox.MaxLengthProperty, value))
                    dgtc.EditingElementStyle = style
                    style.Seal()
                Else
                    setter.Value = value
                End If
            End If
        End Sub
    
        Private Shared Function GetIsMaxLengthSet(ByVal style As Style) As Setter
            If style Is Nothing Then Return Nothing
            Dim setter = style.Setters.LastOrDefault(Function(s) TypeOf s Is Setter AndAlso DirectCast(s, Setter).Property Is TextBox.MaxLengthProperty)
            If setter IsNot Nothing Then Return setter Else Return GetIsMaxLengthSet(style.BasedOn)
        End Function
    
        Private Shared Sub Element_Loaded(ByVal sender As Object, ByVal e As RoutedEventArgs)
            Dim ml = GetMaxLength(sender)
            TextBox_MaxLengthChanged(sender, New DependencyPropertyChangedEventArgs(TextBox.MaxLengthProperty, -1, ml))
            sender.RemoveHandler(FrameworkElement.LoadedEvent, New RoutedEventHandler(AddressOf Element_Loaded))
        End Sub
    End Class
    

    Usage:

    <ComboBox xmlns:loc="MyNamesapace" loc:TextBoxBehavior.MaxLength="50" />