我有一个listview,其selectedIndex绑定到ViewModel。 当ViewModel更改selectedIndex时,listview选择新项目,遗憾的是它没有关注它,如果列表中存在很多项目,那么这对用户来说很烦人。
如何使用XAML更改焦点到selectedItem,或者至少尊重MVVM。
<ListView ItemsSource="{Binding allTags}" ItemTemplate="{StaticResource listTemplate}"
SelectedIndex="{Binding selectedIndex}">
</ListView>
答案 0 :(得分:1)
您可以使用附加行为来关注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);
}
}
}
查看:强>
<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>
查看型号:
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));
}
}