Reputation: 339
I have a listview that has the selectedIndex binded to the ViewModel. When the ViewModel changes the selectedIndex the listview selects the new item, unfortunately it does not focus on it and if a lot items are present in the list then this is annoying for the user.
How can I change to focus to the selectedItem using XAML or at least respecting MVVM.
<ListView ItemsSource="{Binding allTags}" ItemTemplate="{StaticResource listTemplate}"
SelectedIndex="{Binding selectedIndex}">
</ListView>
Upvotes: 0
Views: 662
Reputation: 169200
You could use an attached behaviour to focus the TextBox
:
public static class FocusExtension
{
public static bool GetIsFocused(TextBox textBox)
{
return (bool)textBox.GetValue(IsFocusedProperty);
}
public static void SetIsFocused(TextBox textBox, bool value)
{
textBox.SetValue(IsFocusedProperty, value);
}
public static readonly DependencyProperty IsFocusedProperty =
DependencyProperty.RegisterAttached("IsFocused", typeof(bool), typeof(FocusExtension),
new UIPropertyMetadata(false, OnIsFocusedPropertyChanged));
private static void OnIsFocusedPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
TextBox textBox = d as TextBox;
if ((bool)e.NewValue)
{
textBox.Dispatcher.BeginInvoke(new Action(()=>
{
Keyboard.Focus(textBox);
}), DispatcherPriority.Background);
}
}
}
View:
<Window.DataContext>
<local:TestWindowViewModel></local:TestWindowViewModel>
</Window.DataContext>
<Window.Resources>
<DataTemplate x:Key="template">
<TextBox x:Name="listItemTextBox">
<TextBox.Style>
<Style TargetType="TextBox">
<Style.Triggers>
<DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType=ListViewItem}}" Value="True">
<Setter Property="local:FocusExtension.IsFocused" Value="True" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
</DataTemplate>
</Window.Resources>
<StackPanel>
<ListView ItemsSource="{Binding myList}" ItemTemplate="{StaticResource template}" SelectedIndex="{Binding SelectedIndex}"></ListView>
</StackPanel>
View Model:
public class TestWindowViewModel : INotifyPropertyChanged
{
public List<string> myList { get; set; }
private int _selectedIndex;
public int SelectedIndex
{
get { return _selectedIndex; }
set { _selectedIndex = value; }
}
public TestWindowViewModel()
{
myList = new List<string> { "one", "two", "three" };
SelectedIndex = 1;
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Upvotes: 1