2011-01-23 4 views
5

Кто-нибудь знает о свободной или коммерческой управления WPF, что бы сделать что-то вроде этого:сегментированные текстовое поле в WPF

alt text

X символ в поле, и авто-табуляции в следующем окне, как вы заполните каждый коробка? Аналогично тому, как лицензионные ключи вводятся для продуктов Microsoft.

Я не думаю, что это было бы особенно сложно сделать с нуля, но я бы хотел избежать повторного использования колеса, если хороший пример этого уже существует.

ответ

4

WPF предоставляет все необходимое, кроме автоматического табуляции, для следующего элемента управления. Поведение может обеспечить эту функциональность и результат выглядит следующим образом:

<Grid> 
    <Grid.Resources> 
     <local:KeyTextCollection x:Key="keys"/> 
    </Grid.Resources> 
    <StackPanel> 
     <ItemsControl ItemsSource="{StaticResource keys}" Focusable="False"> 
      <ItemsControl.ItemsPanel> 
       <ItemsPanelTemplate> 
        <StackPanel Orientation="Horizontal" Background="AliceBlue"/> 
       </ItemsPanelTemplate> 
      </ItemsControl.ItemsPanel> 
      <ItemsControl.ItemTemplate> 
       <DataTemplate> 
        <TextBox Text="{Binding Text}" Margin="5" MaxLength="4" Width="40"> 
         <i:Interaction.Behaviors> 
          <local:TextBoxBehavior AutoTab="True" SelectOnFocus="True"/> 
         </i:Interaction.Behaviors> 
        </TextBox> 
       </DataTemplate> 
      </ItemsControl.ItemTemplate> 
     </ItemsControl> 
    </StackPanel> 
</Grid> 

Вот классы KeyText и KeyTextCollection (Подогнать по вкусу):

class KeyText 
{ 
    public string Text { get; set; } 
} 

class KeyTextCollection : List<KeyText> 
{ 
    public KeyTextCollection() 
    { 
     for (int i = 0; i < 4; i++) Add(new KeyText { Text = "" }); 
    } 
} 

А вот поведение, которое реализует автоматическую вкладку и выбрать-на-фокус:

public class TextBoxBehavior : Behavior<TextBox> 
{ 
    public bool SelectOnFocus 
    { 
     get { return (bool)GetValue(SelectOnFocusProperty); } 
     set { SetValue(SelectOnFocusProperty, value); } 
    } 

    public static readonly DependencyProperty SelectOnFocusProperty = 
     DependencyProperty.Register("SelectOnFocus", typeof(bool), typeof(TextBoxBehavior), new UIPropertyMetadata(false)); 

    public bool AutoTab 
    { 
     get { return (bool)GetValue(AutoTabProperty); } 
     set { SetValue(AutoTabProperty, value); } 
    } 

    public static readonly DependencyProperty AutoTabProperty = 
     DependencyProperty.Register("AutoTab", typeof(bool), typeof(TextBoxBase), new UIPropertyMetadata(false)); 

    protected override void OnAttached() 
    { 
     AssociatedObject.PreviewGotKeyboardFocus += (s, e) => 
     { 
      if (SelectOnFocus) 
      { 
       Action action =() => AssociatedObject.SelectAll(); 
       AssociatedObject.Dispatcher.BeginInvoke(action, DispatcherPriority.ContextIdle); 
      } 
     }; 
     AssociatedObject.TextChanged += (s, e) => 
     { 
      if (AutoTab) 
      { 
       if (AssociatedObject.Text.Length == AssociatedObject.MaxLength && 
        AssociatedObject.SelectionStart == AssociatedObject.MaxLength) 
       { 
        AssociatedObject.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next)); 
       } 
      } 
     }; 
    } 
} 

Если вы не знакомы с поведением, установите Expression Blend 4 SDK и добавить пространство имен:

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" 

и добавьте System.Windows.Interactivity в ваш проект.

+0

спасибо - я попробую и посмотрю, делает ли он то, что мне нужно – Jason

Смежные вопросы