在将新项目添加到列表框后,如何使文本框选择所有文本?

时间:2013-12-02 20:57:22

标签: wpf

我的页面上有一个ListBox,其中包含一些项目的名称。 ListBox右侧是一个显示所选项目信息的区域。

当用户单击“添加项目”按钮时,将使用自动生成的名称创建新项目,例如“新项目”。我希望能够立即将项目添加到ListBox后,关注TextBox并选择所有选定的文本,这样如果他们开始输入它会立即替换自动生成的文本。

以下是对它的外观的概念:

enter image description here

我创建了一个附加到ListBox的行为,它在创建新项目时给出了TextBox焦点。但是,我在尝试选择文本时遇到问题。在我的行为执行时,新名称尚未绑定。因此,例如,如果我选择了“第三项”,然后单击“添加项目”按钮,当行为执行时,文本框的文本仍然是“第三项”,我选择了所有这些,但随后TextBox更新的绑定并将其更改为“新项目”,并且不再选择该文本。

这是我的行为:

public class ListBoxFocusAnotherControlOnAddBehavior : Behavior<ListBox>
    {
        public static readonly DependencyProperty AttachedTextBoxProperty = DependencyProperty.Register("AttachedTextBox", typeof (TextBox),
            typeof (ListBoxFocusAnotherControlOnAddBehavior), new PropertyMetadata(default(TextBox)));

        public TextBox AttachedTextBox
        {
            get { return (TextBox)GetValue(AttachedTextBoxProperty); }
            set { SetValue(AttachedTextBoxProperty, value); }
        }

        protected override void OnAttached()
        {
            ((INotifyCollectionChanged)AssociatedObject.Items).CollectionChanged += onListBoxCollectionChanged;
        }

        private void onListBoxCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (e.Action == NotifyCollectionChangedAction.Add)
            {
                AttachedTextBox.Focus();
                AttachedTextBox.SelectAll();
                // The problem being that at the time of this SelectAll, the TextBox's Text binding hasn't updated yet.
            }
        }
    }

相关XAML:

<ListBox Name="ThingsList" ItemsSource="{Binding Things}" SelectedItem="{Binding SelectedThing}">
    <i:Interaction.Behaviors>
        <behaviors:ListBoxFocusAnotherControlOnAddBehavior AttachedTextBox="{Binding ElementName=ThingNameTextBox}" />
    </i:Interaction.Behaviors>
    <ListBox.ItemTemplate>
        <DataTemplate DataType="{x:Type ThingViewModel}">
            <TextBlock Text="{Binding Path=Name, UpdateSourceTrigger=PropertyChanged}" />
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

<TextBox Name="ThingNameTextBox"  Text="{Binding Path=SelectedThing.Name, UpdateSourceTrigger=PropertyChanged}" />  

我能做些什么来获得我正在寻找的行为?

1 个答案:

答案 0 :(得分:1)

我确实找到了一个可行的解决方案,涉及从处理程序订阅TextChanged事件,选择处理后的所有文本,然后删除事件,但这感觉非常糟糕,我喜欢某事这不是一个黑客攻击。

private void onListBoxCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    if (e.Action == NotifyCollectionChangedAction.Add)
    {
        AttachedTextBox.Focus();
        AttachedTextBox.TextChanged += AttachedTextBox_TextChanged;
    }
}

private void AttachedTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
    AttachedTextBox.SelectAll();
    AttachedTextBox.TextChanged -= AttachedTextBox_TextChanged;
}