ListBox Selected Items in WPF using MVVM

2019-09-11 03:11发布

I have a ListBox in WPF and it has CheckBox items inside. I'm splitting the checked checkboxes with the following code in XAML codebehind.

StringBuilder sbMonths = new StringBuilder();
StringBuilder sbMonthNames = new StringBuilder();

string months;
string monthNames;

foreach (var item in ListBox.Items)
{
    if (item is CheckBox)
    {
        var chk = item as CheckBox;

        if ((bool)chk.IsChecked)
        {
            sbMonths.Append(chk.Tag);
            sbMonths.Append(',');

            sbMonthNames.Append(chk.Content.ToString());
            sbMonthNames.Append('-');
        }
    }

}

months = sbMonths.ToString();
monthNames = sbMonthNames.ToString();
int lastIndexOfMonths = months.LastIndexOf(',');
int lastIndexOfMonthNames = monthNames.LastIndexOf('-');

if (lastIndexOfMonths > -1)
{
    months = months.Remove(lastIndexOfMonths);
    monthNames = monthNames.Remove(lastIndexOfMonthNames);
    .... I do more here
}

The thing is that I have no idea how to do this using MVVM. Would you provide some solutions?

XAML:

<ListBox Name="ListBox" HorizontalAlignment="Left" Height="149" Margin="23,47,0,0" VerticalAlignment="Top" Width="210">
    <ComboBoxItem Content="-- Ay Seçiniz --"/>
    <CheckBox Content="Ocak" Tag="1"/>
    <CheckBox Content="Şubat" Tag="2"/>
    <CheckBox Content="Mart" Tag="3"/>
    <CheckBox Content="Nisan" Tag="4"/>
    <CheckBox Content="Mayıs" Tag="5"/>
    <CheckBox Content="Haziran" Tag="6"/>
    <CheckBox Content="Temmuz" Tag="7"/>
    <CheckBox Content="Ağustos" Tag="8"/>
    <CheckBox Content="Eylül" Tag="9"/>
    <CheckBox Content="Ekim" Tag="10"/>
    <CheckBox Content="Kasım" Tag="11"/>
    <CheckBox Content="Aralık" Tag="12"/>
</ListBox>

标签: wpf mvvm
2条回答
欢心
2楼-- · 2019-09-11 03:27

Here's how you would do this using MVVM.

First, create a Model (MVVM) for your months.

public class Month
{
    public string Name {get;set;}
    public int Index {get;set;} // or whatever else you need
    public bool Selected {get;set;}
}

Now, you want to expose those in your ViewModel (MVVM) both as a collection of all months.

public class ViewModel
{
    // init this in your ctor
    public ObservableCollection<Month> Months {get;private set;}
    // snip

And then bind to them in your View (MVVM)

<ListBox ItemsSource="{Binding Months}"> 
    <ListBox.ItemTemplate>
      <DataTemplate>
          <CheckBox IsChecked="{Binding Selected}" Content="{Binding Name}"/>
      </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

That's how MVVM works.

查看更多
走好不送
3楼-- · 2019-09-11 03:35

Use Following Code:

XAML:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication1"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <ListBox ItemsSource="{Binding Months}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <CheckBox IsChecked="{Binding IsSelected,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Content="{Binding MonthName}" />
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>
</Window>

Code:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Linq.Expressions;
using System.Printing;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = new MainViewModel();
        }
    }

    public class MainViewModel : BaseViewModel
    {
        public ObservableCollection<MonthViewModel> Months { get; set; }

        public MainViewModel()
        {
            this.Months = new ObservableCollection<MonthViewModel>();

            this.Months.Add(new MonthViewModel() { MonthName = "Ocak", MonthNumber = 1 });
            this.Months.Add(new MonthViewModel() { MonthName = "Şubat", MonthNumber = 2 });
            this.Months.Add(new MonthViewModel() { MonthName = "Mart", MonthNumber = 3 });
            this.Months.Add(new MonthViewModel() { MonthName = "Nisan", MonthNumber = 4 });
            this.Months.Add(new MonthViewModel() { MonthName = "Mayıs", MonthNumber = 5 });
            this.Months.Add(new MonthViewModel() { MonthName = "Haziran", MonthNumber = 6 });
            this.Months.Add(new MonthViewModel() { MonthName = "Temmuz", MonthNumber = 7 });
            this.Months.Add(new MonthViewModel() { MonthName = "Ağustos", MonthNumber = 8 });
            this.Months.Add(new MonthViewModel() { MonthName = "Eylül", MonthNumber = 9 });
            this.Months.Add(new MonthViewModel() { MonthName = "Ekim", MonthNumber = 10 });
            this.Months.Add(new MonthViewModel() { MonthName = "Kasım", MonthNumber = 11 });
            this.Months.Add(new MonthViewModel() { MonthName = "Aralık", MonthNumber = 12 });
        }
    }

    public class MonthViewModel : BaseViewModel
    {
        private string _monthName;
        public string MonthName
        {
            get { return _monthName; }
            set
            {
                if (_monthName != value)
                {
                    _monthName = value;
                    this.NotifyOnPropertyChange(() => this.MonthName);
                }
            }
        }

        private bool _isSelected;
        public bool IsSelected
        {
            get { return _isSelected; }
            set
            {
                if (_isSelected != value)
                {
                    _isSelected = value;
                    this.NotifyOnPropertyChange(() => this.IsSelected);
                }
            }
        }

        private int _monthNumber;
        public int MonthNumber
        {
            get { return _monthNumber; }
            set
            {
                if (_monthNumber != value)
                {
                    _monthNumber = value;
                    this.NotifyOnPropertyChange(() => this.MonthNumber);
                }
            }
        }
    }

    public class BaseViewModel : INotifyPropertyChanged
    {
        #region INotifyPropertyChanged Members
        public event PropertyChangedEventHandler PropertyChanged;
        public void NotifyOnPropertyChange(Expression<Func<object>> expression)
        {
            if (PropertyChanged != null)
            {
                if (expression.NodeType != ExpressionType.Lambda)
                    throw new ArgumentException("Value must be a lamda expression", "expression");

                var body = expression.Body as MemberExpression;

                if (body == null)
                {
                    throw new ArgumentException("'expression' should have a Body of type MemberExpression");
                }

                string propertyName = body.Member.Name;
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }

        }
        #endregion
    }
}

Using above code at any point of time in ViewModel, you will be able to get the selected items from collection Months and you can apply your code as you want.

查看更多
登录 后发表回答