如何在WPF中设置组合框的maxlength?

时间:2009-10-15 14:49:22

标签: wpf combobox maxlength

如何将maxlength设置为应用了样式的组合框。

谢谢

6 个答案:

答案 0 :(得分:23)

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

答案 1 :(得分:7)

或者您可以使用组合框的GotFocus或Loaded事件来设置maxlength。如果maxlength doest在运行时更改太多,您可以使用加载的事件或者使用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 :(得分:2)

你是对的。文本框有一个最大长度,但组合框没有。您必须使用文本框作为中介来滚动自己。这是一些代码:

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

答案 3 :(得分:0)

此TextBox将为null。 给出的风格如下。

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

答案 4 :(得分:0)

我使用了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 :)
        }
    }
}

答案 5 :(得分:-1)

我通过XAML找到了简单的解决方案。在comboBox资源中,我们可以设置textbox的样式,并通过setter set 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。对于通常的comboBox来完成这项工作,看看here