wpf之ListBox

发布于:2025-08-29 ⋅ 阅读:(24) ⋅ 点赞:(0)

前言

wpf中ListBox在针对多个选项选择中的应用十分广泛,本文就来讲解非Mvvm和Mvvm模式下如何使用ListBox。

1、非MVVM模式下

xaml代码:
ListBoxItem用于存储ListBox的每一项,可以设置ListBoxItem的属性,比如Foreground控制项的字体颜色;Background来控制项的背景色;为ListBox注册SelectionChanged事件,该事件代码在MainWindow窗体类中。

 <ListBox x:Name="ListBox_test" SelectionChanged="ListBox_SelectionChanged">
                <ListBoxItem Foreground="White"  Background="Red"   >项目1</ListBoxItem>
                <ListBoxItem>项目2</ListBoxItem>
                <ListBoxItem>项目3</ListBoxItem>
                <ListBoxItem>项目4</ListBoxItem>
            </ListBox >

MainWindow窗体类

 public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = new ViewModel();
        }

        private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            var item = ListBox_test.SelectedItem;
        }
    }

运行结果:
在这里插入图片描述

2、MVVM模式下

2.1 SelectionMode为Single

xaml代码:
1)mvvm模式下使用绑定来为ListBox添加数据,通过为ItemsSource绑定ViewModel中的Items属性
2)然后为了获取ListBox中用户选择的哪一项,为SelectedItem绑定ViewModel中的divisionType属性
但是由于SelectedItem是object类型,divisionType是枚举类型,无法直接绑定,所以要使用类型转换


  <Window.Resources>
        <local:DivisionTypeToString x:Key="DivisionTypeToString"/>
    </Window.Resources>
 <ListBox SelectionMode="Single" ItemsSource="{Binding Items }" Foreground="Red"  SelectedItem="{Binding divisionType, Converter={StaticResource DivisionTypeToString}}"  > 
 </ListBox >

添加类型转换
下面的Convert方法用于将DivisionType转换成字符串,ConvertBack用于将字符串转换成DivisionType

 public  class DivisionTypeToString: IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            DivisionType divisionType = (DivisionType)value;
            return divisionType.ToString ();
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            DivisionType divisionType  =(DivisionType)Enum.Parse(typeof (DivisionType),value .ToString ());
            return divisionType;
        }
    }

添加 Model类

public enum DivisionType
{
    分时1,
    分时2
}

添加ViewModelBase类

 public class ViewModelBase
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public void OnPropertyChanged(string propname)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propname));
            }
        }

    }

添加ViewModel类

 public class ViewModel : ViewModelBase
    {
       
        public ViewModel()
        {
            Items = new List<string>();
            Items.Add("分时1");
            Items.Add("分时2");
        }
        private List<string> items;

        public List<string> Items
        {
            get
            {
                return items;
            }
            set
            {
                this.items = value;
                OnPropertyChanged("Items");
            }
        }



        private DivisionType _divisionType = DivisionType.分时1;
        public DivisionType divisionType
        {
            get
            {
                return _divisionType;
            }
            set
            {
                this._divisionType = value;
                OnPropertyChanged("divisionType");
            }
        }
    }

运行结果:
在这里插入图片描述

2.2 SelectionMode为Multiple

xaml代码:
1)mvvm模式下使用绑定来为ListBox添加数据,通过为ItemsSource绑定ViewModel中的Items属性
2)又因为是多选,所以不能使用SelectedItem属性的绑定,得使用 SelectionChanged事件,然后在事件中获取SelectedItems属性从而获取所有用户选择的项,所以这里使用使用Interaction.Trigger,EventName指定绑定的事件名称,CommandSelectionChanged是绑定的ViewModel中的命令。(这里要注意使用Interaction.Triggers需要引用System.Windows.Interactivity.dll)


  <Window.Resources>
        <local:DivisionTypeToString x:Key="DivisionTypeToString"/>
    </Window.Resources>
 <ListBox x:Name="listBox_test2" SelectionMode="Multiple" ItemsSource="{Binding Items }" Foreground="Red"     >
                <Event:Interaction.Triggers>
                    <Event:EventTrigger EventName="SelectionChanged">
                        <Event:InvokeCommandAction Command="{Binding CommandSelectionChanged}" CommandParameter="{Binding ElementName=listBox_test2}"/>
                    </Event:EventTrigger>
                </Event:Interaction.Triggers>
            </ListBox >

添加DelegateCommand

 public class DelegateCommand : ICommand
    {
        private readonly Action<object> _execute;
        private readonly Func<object, bool> _canExecute;

        public DelegateCommand(Action<object> execute, Func<object, bool> canExecute = null)
        {
            _execute = execute ?? throw new ArgumentNullException(nameof(execute));
            _canExecute = canExecute;
        }

        public bool CanExecute(object parameter)
        {
            if (_canExecute != null)
            {
                return _canExecute(parameter);
            }
            else
            {
                return true;
            }
        }

        public void Execute(object parameter)
        {
            _execute(parameter);
        }


        public event EventHandler CanExecuteChanged
        {
            add => CommandManager.RequerySuggested += value;
            remove => CommandManager.RequerySuggested -= value;
        }

        public void RaiseCanExecuteChanged()
        {
            CommandManager.InvalidateRequerySuggested();
        }
    }

添加 Model类

public enum DivisionType
{
    分时1,
    分时2
}

添加ViewModelBase类

 public class ViewModelBase
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public void OnPropertyChanged(string propname)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propname));
            }
        }

    }

添加ViewModel类

 public class ViewModel : ViewModelBase
    {
        public ICommand CommandSelectionChanged { get; set; }
        public ViewModel()
        {
            Items = new List<string>();
            Items.Add("分时1");
            Items.Add("分时2");
            CommandSelectionChanged = new DelegateCommand(ListBoxSelectionChanged);
        }
        private List<string> items;

        public List<string> Items
        {
            get
            {
                return items;
            }
            set
            {
                this.items = value;
                OnPropertyChanged("Items");
            }
        }


        private ObservableCollection<DivisionType> _divisionTypeList = new ObservableCollection<DivisionType>();
        public ObservableCollection<DivisionType> divisionTypeList
        {
            get
            {
                return _divisionTypeList;
            }
            set
            {
                this._divisionTypeList = value;
                OnPropertyChanged("divisionTypeList");
            }
        }

        private void ListBoxSelectionChanged(object obj)
        {
            divisionTypeList.Clear();
            ListBox listBox =(ListBox) obj;
            foreach ( var item in listBox.SelectedItems)
            {
                DivisionType divisionType=(DivisionType) Enum.Parse(typeof (DivisionType),item.ToString ());
                divisionTypeList.Add(divisionType);
            }
            
        }
    }

运行结果:
在这里插入图片描述

马工撰写的年入30万+C#上位机项目实战必备教程(点击下方链接即可访问文章目录)

1、《C#串口通信从入门到精通》
2、《C#与PLC通信从入门到精通 》
3、《C# Modbus通信从入门到精通》
4、《C#Socket通信从入门到精通 》
5、《C# MES通信从入门到精通》
6、《winform控件从入门到精通》
7、《C#操作MySql数据库从入门到精通》


网站公告

今日签到

点亮在社区的每一天
去签到