在ListBox中选择下一个/上一个项目的按钮命令

本文关键字:项目 按钮 命令 上一个 ListBox 选择 下一个 | 更新日期: 2023-09-27 17:59:06

有没有一个简单的命令可以用按钮发送到标准的WPF ListBox,让它选择列表中的下一个/上一个项目?

目前我正在使用这个解决方案:

            <Button Width="30" Height="30" x:Name="PreviousButton">
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="Click">
                        <ei:ChangePropertyAction Increment="True"
                                                 PropertyName="SelectedIndex"
                                                 TargetName="MyListBox"
                                                 Value="-1" />
                    </i:EventTrigger>
                </i:Interaction.Triggers>
            </Button>
           <!-- ListBox would be here. -->
           <Button Width="30" Height="30" x:Name="NextButton">
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="Click">
                        <ei:ChangePropertyAction Increment="True"
                                                 PropertyName="SelectedIndex"
                                                 TargetName="MyListBox"
                                                 Value="1" />
                    </i:EventTrigger>
                </i:Interaction.Triggers>
            </Button>

这很好。如果您在列表的第一个项目(与最后一个项目相同)上点击了上一个按钮,则会导致异常,但当前的计划是,如果所选的索引是列表中的第一个/最后一个项,则会告诉它禁用该按钮。

我问这个问题只是想看看我是否错过了一个技巧。如果是这样的话,"不,那是不可能的,你必须用另一种方式"是一个完全可以接受的答案。

在ListBox中选择下一个/上一个项目的按钮命令

使用mvvm会很好而且更简单。这就是我将要解决的问题。注意,我的示例代码使用mvvmLight工具包。

查看

<Window x:Class="StackOverFlow1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:StackOverFlow1"
        xmlns:viewModel="clr-namespace:StackOverFlow1.ViewModel"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <viewModel:MainViewModel x:Key="MainViewModel"/>
    </Window.Resources>
    <Grid DataContext="{StaticResource MainViewModel}">
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <ListBox Grid.Row="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ItemsSource="{Binding Students}" x:Name="ListBox"
                 SelectedIndex="{Binding SelectedIndex}"/>
        <StackPanel Orientation="Horizontal" Grid.Row="1">
            <Button Content="Next" Width="50" Height="24" Command="{Binding NextCommand}" CommandParameter="{Binding ElementName=ListBox,Path=SelectedIndex}"/>
            <Button Content="Previous" Width="50" Height="24" Command="{Binding PreviousCommand}" CommandParameter="{Binding ElementName=ListBox,Path=SelectedIndex}"/>
        </StackPanel>
    </Grid>
</Window>

ViewModel

using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows.Input;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.CommandWpf;
namespace StackOverFlow1.ViewModel
{
    public class MainViewModel : ViewModelBase
    {
        public MainViewModel()
        {
         NextCommand=new RelayCommand<int>(OnNext,CanNext);
         PreviousCommand=new RelayCommand<int>(OnPrevious,CanPrevious);
            SelectedIndex = 0;
            foreach (var student in GetStudent())
            {
                _students.Add(student);
            }
        }
        public ICommand NextCommand { get; set; }
        public ICommand PreviousCommand { get; set; }
        private int _selectedIndex;

        private List<Student> GetStudent()
        {
            return new List<Student>()
            {
                new Student {Id = 0,Name = "Kwame0"},
                 new Student {Id = 0,Name = "Kwame1"},
                 new Student {Id = 0,Name = "Kwame2"},
                 new Student {Id = 0,Name = "Kwame3"},
                  new Student {Id = 0,Name = "Kwame4"},
                 new Student {Id = 0,Name = "Kwame5"},
                 new Student {Id = 0,Name = "Kwame6"},
                 new Student {Id = 0,Name = "Kwame7"},
                   new Student {Id = 0,Name = "Kwame8"},
                 new Student {Id = 0,Name = "Kwame9"},
                 new Student {Id = 0,Name = "Kwame10"},
                 new Student {Id = 0,Name = "Kwame11"},
                  new Student {Id = 0,Name = "Kwame12"},
                 new Student {Id = 0,Name = "Kwame13"},
                 new Student {Id = 0,Name = "Kwame14"},
                 new Student {Id = 0,Name = "Kwame15"},
            };
        }
        public int SelectedIndex
        {
            get { return _selectedIndex; }
            set { _selectedIndex = value;RaisePropertyChanged(()=>SelectedIndex); }
        }

        private ObservableCollection<Student> _students=new ObservableCollection<Student>();
        public ObservableCollection<Student> Students
        {
            get { return _students; }
            set { _students = value; }
        }

        private void OnNext(int index)
        {
            if (SelectedIndex != Students.Count)
                SelectedIndex += 1;
            else
            {
                SelectedIndex = 0;
            }
        }
        private bool CanNext(int indext)
        {
            return SelectedIndex != Students.Count;
        }
        private void OnPrevious(int index)
        {
            if (SelectedIndex != 0)
                SelectedIndex -= 1;
            else
            {
                SelectedIndex = Students.Count;
            }
        }
        private bool CanPrevious(int index)
        {
            return SelectedIndex != 0;
        }
    }
    public class Student
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public override string ToString()
        {
            return $"{Id}-{Name}";
        }
    }
}

它没有"标准"命令,只需创建NextItemCommand和PrevItemCommand即可更改int value;,您可以绑定到ListBox.SelectedIndex,这将是您想要的。关于enable''disable按钮,只需为每个命令传递一个Enabled方法,这样它就会检查value是否可以更改。