我有ListBox
ListBoxItems
的模板,其中包含TextBoxes
当TextBox
聚焦时,我希望选择ListBoxItem
。我发现的一个解决方案看起来像这样:
<Style TargetType="{x:Type ListBoxItem}">
<Style.Triggers>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter Property="IsSelected" Value="True"></Setter>
</Trigger>
</Style.Triggers>
</Style>
这很有效,但当TextBox
失去焦点时,选择也会如此。
有没有办法防止这种情况发生?
答案 0 :(得分:11)
我发现没有代码的最佳解决方案是:
<Style TargetType="{x:Type ListBoxItem}">
<Style.Triggers>
<EventTrigger RoutedEvent="PreviewGotKeyboardFocus">
<BeginStoryboard>
<Storyboard>
<BooleanAnimationUsingKeyFrames
Storyboard.TargetProperty="(ListBoxItem.IsSelected)">
<DiscreteBooleanKeyFrame KeyTime="0" Value="True"/>
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
答案 1 :(得分:0)
您还可以将焦点放在文本框上,但在任何给定时间只选择一个ListBoxItem,后面有代码。
在ListBox XAML中:
<ListBox
PreviewLostKeyboardFocus="CheckFocus">
</ListBox>
然后,在代码隐藏中的CheckFocus()
方法中:
/* Cause the original ListBoxItem to lose focus
* only if another ListBoxItem is being selected.
* If a different element type is selected, the
* original ListBoxItem will keep focus.
*/
private void CheckFocus(object sender, KeyboardFocusChangedEventArgs e)
{
// check if focus is moving from a ListBoxItem, to a ListBoxItem
if (e.OldFocus.GetType().Name == "ListBoxItem" && e.NewFocus.GetType().Name == "ListBoxItem")
{
// if so, cause the original ListBoxItem to loose focus
(e.OldFocus as ListBoxItem).IsSelected = false;
}
}
答案 2 :(得分:0)
从建议的解决方案列表中,没有任何帮助我解决同样的问题。 这是我做的自定义解决方案:
1)。创建将强制执行焦点的行为(包含附加属性的类):
public class TextBoxBehaviors
{
public static bool GetEnforceFocus(DependencyObject obj)
{
return (bool)obj.GetValue(EnforceFocusProperty);
}
public static void SetEnforceFocus(DependencyObject obj, bool value)
{
obj.SetValue(EnforceFocusProperty, value);
}
// Using a DependencyProperty as the backing store for EnforceFocus. This enables animation, styling, binding, etc...
public static readonly DependencyProperty EnforceFocusProperty =
DependencyProperty.RegisterAttached("EnforceFocus", typeof(bool), typeof(TextBoxBehaviors), new PropertyMetadata(false,
(o, e) =>
{
bool newValue = (bool)e.NewValue;
if (!newValue) return;
TextBox tb = o as TextBox;
if (tb == null)
{
MessageBox.Show("Target object should be typeof TextBox only. Execution has been seased", "TextBoxBehaviors warning",
MessageBoxButton.OK, MessageBoxImage.Warning);
}
tb.TextChanged += OnTextChanged;
}));
private static void OnTextChanged(object o, TextChangedEventArgs e)
{
TextBox tb = o as TextBox;
tb.Focus();
/* You have to place your caret at the end of your text manually, because each focus repalce your caret at the beging of text.*/
tb.CaretIndex = tb.Text.Length;
}
}
2)。在XAML中使用此行为:
<DataTemplate x:Key="MyDataTemplate">
<TextBox behaviors:TextBoxBehaviors.EnforceFocus="True"
Text="{Binding Path=MyProperty, UpdateSourceTrigger=PropertyChanged}" />
</DataTemplate>