У меня есть ListBox
с редактируемыми элементами.Когда вы редактируете элемент в первый раз, элемент управления редактирования (a TextBox
в этом минимальном примере) изначально имеет фокус клавиатуры.При втором редактировании элемента TextBox
не имеет фокусировки клавиатуры.Если вы тестируете код, элементы переводятся в режим редактирования, выбирая их и нажимая F2 или Return.
Есть ли какой-нибудь разумный и прямой способ заставить TextBox
всегда получать фокус клавиатуры, когда он становится видимым?В противном случае, есть ли необоснованный или косвенный способ, который работает надежно?
Не всегда возможно использовать шаблон редактирования, потому что настоящий шаблон редактирования включает в себя много вещей, таких как высота 300 пикселей ListBox
с тысячей опций и TextBox
для фильтрации содержимогоиз ListBox
.Я пытался сделать это с CellTemplate
из DevExpress GridControl , но это было червем по разным причинам.
Причина, по которой я поочередно показываю / скрываю два элемента управления контентом, заключается в том, что когда я просто меняю различные шаблоны в ListBox.ItemTemplate
, фокус переходит на окно.
XAML:
<Window.DataContext>
<local:ViewModel />
</Window.DataContext>
<Grid>
<ListBox
ItemsSource="{Binding Items}"
>
<ListBox.Resources>
<DataTemplate x:Key="DisplayTemplate">
<Label Content="{Binding Value}" />
</DataTemplate>
<DataTemplate x:Key="EditTemplate">
<WrapPanel FocusManager.FocusedElement="{Binding ElementName=TextBox}" Focusable="False">
<Label>Editing:</Label>
<TextBox Margin="4,2,2,2" Text="{Binding Value}" x:Name="TextBox" />
</WrapPanel>
</DataTemplate>
</ListBox.Resources>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<ContentControl x:Name="Display" Content="{Binding}" ContentTemplate="{StaticResource DisplayTemplate}" />
<ContentControl x:Name="Edit" Content="{Binding}" ContentTemplate="{StaticResource EditTemplate}" Visibility="Collapsed" />
</Grid>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding IsEditing}" Value="True">
<Setter TargetName="Edit" Property="Visibility" Value="Visible" />
<Setter TargetName="Display" Property="Visibility" Value="Collapsed" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem" BasedOn="{StaticResource {x:Type ListBoxItem}}">
<EventSetter Event="KeyDown" Handler="ListBoxItem_KeyDown" />
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
</Grid>
ViewModels.cs
public class ViewModel : ViewModelBase
{
public ViewModel()
{
Items = new ObservableCollection<ItemViewModel>(
new[] { "ytesadamy", "ugexudunamo", "wovaxatytol", "imuq" }.Select(s => new ItemViewModel() { Value = s }));
}
public ObservableCollection<ItemViewModel> Items { get; private set; }
}
public class ItemViewModel : ViewModelBase
{
#region Value Property
private String _value = default(String);
public String Value
{
get { return _value; }
set
{
if (value != _value)
{
_value = value;
OnPropertyChanged();
}
}
}
#endregion Value Property
#region IsEditing Property
private bool _isEditing = default(bool);
public bool IsEditing
{
get { return _isEditing; }
set
{
if (value != _isEditing)
{
_isEditing = value;
OnPropertyChanged();
}
}
}
#endregion IsEditing Property
}
#region ViewModelBase Class
public class ViewModelBase : INotifyPropertyChanged
{
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string propName = null) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
#endregion INotifyPropertyChanged
}
#endregion ViewModelBase Class