2009-10-15 66 views

回答

19

當使用DependencyProperty時,我們可以在不修改樣式/模板的情況下設置組合框的最大長度。

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

用例:

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

哪裏ComboboxHelper是:

的xmlns:ComboboxHelper = 「clr- 名稱空間:yourNameSpace;裝配= yourAssembly

comboBox.FindChild(...)方法過帳here

+0

非常感謝Tri Q ..再次感謝你。 – Ershad 2009-10-21 11:47:48

2

你是對的。 Textbox有一個最大長度,但不能用於組合框。您必須使用Textbox作爲中介來推出自己的產品。以下是一些代碼:

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

此TextBox將爲空。 給出的風格如下。

<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

或者你可以使用在GotFocus或組合框設置maxlength.If的最大長度的Loaded事件在運行時所行的變化太大了,你可以使用加載事件或者使用GotFocus事件

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

,並在各自的事件...

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

我通過XAML找到了簡單的解決方案。在comboBox資源中,我們可以爲文本框設置樣式,並通過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> 

編輯:這適用於Actipro組合框。對於通常的comboBox來使這項工作,看看here

-2

我用PreviewKeyDown事件,很簡單+你可以顯示警告或什麼的。
將以下方法註冊到您的ComboBox.PreviewKeyDown + =事件中,
如果用戶按空間鍵,則不會觸發KeyDown事件。

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