当selectedIndex因绑定而更改时,请关注选定的ListViewItem

时间:2017-02-02 11:15:41

标签: xaml listview mvvm focus selecteditem

我有一个listview,其selectedIndex绑定到ViewModel。 当ViewModel更改selectedIndex时,listview选择新项目,遗憾的是它没有关注它,如果列表中存在很多项目,那么这对用户来说很烦人。

如何使用XAML更改焦点到selectedItem,或者至少尊重MVVM。

<ListView ItemsSource="{Binding allTags}" ItemTemplate="{StaticResource listTemplate}" 
          SelectedIndex="{Binding selectedIndex}">
</ListView>

1 个答案:

答案 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));
    }
}