关于c#:按钮命令以选择列表框中的下一个/上一个项目

Button command(s) to select next / previous item in ListBox

我是否可以使用一个按钮将一个简单的命令发送到标准WPF列表框,该按钮将使其选择列表中的下一个/上一个项目?

目前,我正在使用以下解决方案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
            <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>

哪个好。如果您在列表的第一项上(与最后一项相同)时单击上一个按钮,则确实会导致异常,但是当前计划是告诉它,如果selectedindex是列表中的第一项/最后一项,则禁用该按钮。列表。

我在问这个问题只是为了看看我是否比其他任何东西都缺少技巧。如果是这样,"不,那是不可能的,您必须以其他方式来做"是一个完全可以接受的答案。


使用mvvm会更好,更简单。这就是我要解决的方式。请注意,我的示例代码使用mvvmLight工具箱。

查看

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
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}";
        }
    }
}


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