2009-10-15 14 views

Respuesta

19

cuando se utiliza DependencyProperty, podemos establecer el maxlength del cuadro combinado sin modificar su estilo/plantilla. ejemplo

public class EditableComboBox 
{ 

    public static int GetMaxLength(DependencyObject obj) 
    { 
     return (int)obj.GetValue(MaxLengthProperty); 
    } 

    public static void SetMaxLength(DependencyObject obj, int value) 
    { 
     obj.SetValue(MaxLengthProperty, value); 
    } 

    // Using a DependencyProperty as the backing store for MaxLength. This enables animation, styling, binding, etc... 
    public static readonly DependencyProperty MaxLengthProperty = DependencyProperty.RegisterAttached("MaxLength", typeof(int), typeof(EditableComboBox), new UIPropertyMetadata(OnMaxLenghtChanged)); 

    private static void OnMaxLenghtChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) 
    { 
     var comboBox = obj as ComboBox; 
     if (comboBox == null) return; 

     comboBox.Loaded += 
      (s, e) => 
      { 
       var textBox = comboBox.FindChild(typeof(TextBox), "PART_EditableTextBox"); 
       if (textBox == null) return; 

       textBox.SetValue(TextBox.MaxLengthProperty, args.NewValue); 
      }; 
    } 
} 

Uso:

<ComboBox ComboboxHelper:EditableComboBox.MaxLength="50" /> 

Dónde ComboboxHelper es:

xmlns: ComboboxHelper = "clr- espacio de nombres: yourNameSpace; montaje = YourAssembly"

comboBox.FindChild (...) método se publica here.

+0

Muchas gracias Tri Q .. Una vez más, gracias. – Ershad

2

Usted está correcto. Hay una longitud máxima para un cuadro de texto, pero no para un cuadro combinado. Tienes que hacer tu propio uso de un cuadro de texto como intermediario. Aquí hay un código:

public int MaxLength {get; set;} 
protected override void OnGotFocus(System.Windows.RoutedEventArgs e) 
{ 
    base.OnGotFocus(e); 
    TextBox thisTextBox = (TextBox)base.GetTemplateChild("PART_EditableTextBox"); 
    if (thisTextBox != null) 
     thisTextBox.MaxLength = MaxLength; 
} 
0

Este TextBox está llegando a nulo. El estilo dado es el siguiente.

<ControlTemplate x:Key="ComboBoxToggleButton" TargetType="ToggleButton"> 
     <Grid> 
      <Grid.ColumnDefinitions> 
       <ColumnDefinition Width="*" /> 
       <ColumnDefinition Width="{Binding Path=(local:ToggleComboBox.Width), 
        RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ComboBox}}}" /> 
      </Grid.ColumnDefinitions> 
      <Border x:Name="Border" 
        Grid.Column="1" 
        CornerRadius="2" 
        Background="#CCFFCC" 
        BorderBrush="#000080" 
        BorderThickness="4" /> 

      <Border Grid.Column="0" 
        CornerRadius="8,8,8,8" 
        Margin="0" 
        Background="#CCFFCC" 
        BorderBrush="#000080" 
        BorderThickness="4,4,4,4" /> 

      <Image x:Name="Arrow" 
        Grid.Column="1"  
        Source="Arrow.png" Margin="4,4,4,4" 
        HorizontalAlignment="Center" 
        VerticalAlignment="Center"/> 
     </Grid> 
     <ControlTemplate.Triggers> 
      <Trigger Property="ToggleButton.IsMouseOver" Value="true"> 
       <Setter TargetName="Border" Property="Background" Value="{StaticResource DarkBrush}" /> 
      </Trigger> 
      <Trigger Property="ToggleButton.IsChecked" Value="true"> 
       <Setter TargetName="Border" Property="Background" Value="{StaticResource PressedBrush}" /> 
      </Trigger> 
      <Trigger Property="IsEnabled" Value="False"> 
       <Setter TargetName="Border" Property="Background" Value="{StaticResource DisabledBackgroundBrush}" /> 
       <Setter TargetName="Border" Property="BorderBrush" Value="{StaticResource DisabledBorderBrush}" /> 
       <Setter Property="Foreground" Value="{StaticResource DisabledForegroundBrush}"/> 
       <!--<Setter TargetName="Arrow" Property="Fill" Value="{StaticResource DisabledForegroundBrush}" />--> 
      </Trigger> 
     </ControlTemplate.Triggers> 
    </ControlTemplate> 

    <ControlTemplate x:Key="ComboBoxTextBox" TargetType="TextBox"> 
     <Border x:Name="PART_ContentHost" Focusable="False" Background="{TemplateBinding Background}" /> 
    </ControlTemplate> 


    <Style x:Key="ComboBoxStyle" TargetType="ComboBox"> 
     <Setter Property="SnapsToDevicePixels" Value="true"/> 
     <Setter Property="OverridesDefaultStyle" Value="true"/> 
     <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/> 
     <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/> 
     <Setter Property="ScrollViewer.CanContentScroll" Value="true"/> 
     <Setter Property="MinWidth" Value="120"/> 
     <Setter Property="MinHeight" Value="20"/> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="ComboBox"> 
        <Grid> 
         <ToggleButton Name="ToggleButton" 
             Template="{StaticResource ComboBoxToggleButton}" 
             Grid.Column="2" 
             Focusable="false" 
             IsChecked="{Binding Path=IsDropDownOpen, 
                  Mode=TwoWay, 
                  RelativeSource={RelativeSource TemplatedParent}}" 
             ClickMode="Press"/> 

         <ContentPresenter Name="ContentSite" 
              IsHitTestVisible="False" 
              Content="{TemplateBinding SelectionBoxItem}" 
              ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}" 
              ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}" 
              Margin="9,2,28,2" 
              VerticalAlignment="Center" 
              HorizontalAlignment="Left" /> 

         <TextBox x:Name="PART_EditableTextBox" 
           Style="{x:Null}" 
           Template="{StaticResource ComboBoxTextBox}" 
           HorizontalAlignment="Left" 
           VerticalAlignment="Center" 
           Margin="3,3,23,3" 
           Focusable="True" 
           Background="Transparent" 
           Visibility="Hidden" 
           IsReadOnly="{TemplateBinding IsReadOnly}"/> 

         <Popup Name="Popup" 
           Placement="Bottom" 
           IsOpen="{TemplateBinding IsDropDownOpen}" 
           AllowsTransparency="True" 
           Focusable="False" 
           PopupAnimation="Slide"> 

          <Grid Name="DropDown" 
            SnapsToDevicePixels="True"    
            MinWidth="{TemplateBinding ActualWidth}" 
            MaxHeight="{TemplateBinding MaxDropDownHeight}"> 

           <Border x:Name="DropDownBorder" 
             Background="#CCFFCC" 
             BorderBrush="#000080" 
             BorderThickness="2"/> 

           <ScrollViewer Margin="4,6,4,6" SnapsToDevicePixels="True"> 
            <ScrollViewer.Resources> 
             <sys:Double x:Key="{x:Static SystemParameters.VerticalScrollBarWidthKey}">25</sys:Double> 
            </ScrollViewer.Resources>          
            <StackPanel IsItemsHost="True" /> 
           </ScrollViewer> 
          </Grid> 
         </Popup> 
        </Grid> 
        <ControlTemplate.Triggers> 
         <Trigger Property="HasItems" Value="false"> 
          <Setter TargetName="DropDownBorder" Property="MinHeight" Value="95"/> 
         </Trigger> 
         <Trigger Property="IsEnabled" Value="false"> 
          <Setter Property="Foreground" Value="{StaticResource DisabledForegroundBrush}"/> 
         </Trigger> 
         <Trigger Property="IsGrouping" Value="true"> 
          <Setter Property="ScrollViewer.CanContentScroll" Value="false"/> 
         </Trigger> 
         <Trigger SourceName="Popup" Property="Popup.AllowsTransparency" Value="true"> 
          <Setter TargetName="DropDownBorder" Property="CornerRadius" Value="4"/> 
          <Setter TargetName="DropDownBorder" Property="Margin" Value="0,2,0,0"/> 
         </Trigger> 
         <Trigger Property="IsEditable" Value="true"> 
          <Setter Property="IsTabStop" Value="false"/> 
          <Setter TargetName="PART_EditableTextBox" Property="Visibility" Value="Visible"/> 
          <Setter TargetName="ContentSite" Property="Visibility" Value="Hidden"/> 
         </Trigger> 
        </ControlTemplate.Triggers> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
     <Setter Property="ItemContainerStyle" > 
      <Setter.Value> 
       <Style TargetType="{x:Type ComboBoxItem}"> 
        <Setter Property="FontSize" Value="20" /> 
       </Style> 
      </Setter.Value> 
     </Setter> 
    </Style> 
7

O puede utilizar el GotFocus o evento cargado de la lista desplegable para establecer el maxlength.If la maxlength doest cambiar demasiado durante el tiempo de ejecución se puede utilizar el evento cargado o bien utilizar GotFocus evento

<ComboBox Height="30" IsEditable="True" Loaded="ComboBox_Loaded"/> 

y en el evento respectivo ...

var obj = (ComboBox)sender; 
    if (obj != null) 
    { 
     var myTextBox = (TextBox)obj.Template.FindName("PART_EditableTextBox",obj); 
     if (myTextBox != null) 
     { 
      myTextBox.MaxLength = maxLength; 
     } 
    } 
-2

Encontré solución fácil a través de XAML. En los recursos de comboBox podemos establecer el estilo para el cuadro de texto y establecer setter maxlenth.

<ComboBox Name="comboBox" Width="100" IsEditable="True"> 
<ComboBox.Resources> 
<Style TargetType="{x:Type TextBox}"> 
    <Setter Property="MaxLength" Value="yourValue"></Setter> 
</Style> 
</ComboBox.Resources> 
</ComboBox> 

EDITAR: Esto funciona con Actipro ComboBox. Para comboBox habitual para que esto funcione, echar un vistazo here

-2

He utilizado el evento PreviewKeyDown, muy simple + puede mostrar una advertencia o algo así.
Registre el siguiente método en su ComboBox.PreviewKeyDown + = evento,
El evento KeyDown no se activará si el usuario presiona la tecla Espacio.

private void ComboBox_PreviewKeyDown(object sender, KeyEventArgs e) 
{ 
    if (ComboBox.Text.Length > 19) // allow max 20 chars 
    { 
     if (e.Key != Key.Back) // allow removing chars 
     { 
      e.Handled = true; // block any additional key press if there is more than allowed max 
      System.Media.SystemSounds.Beep.Play(); // optional: beep to let user know he is out of space :) 
     } 
    } 
} 
Cuestiones relacionadas