ListBox使用MVVM在WPF中选择的项目

时间:2015-05-14 13:14:29

标签: wpf mvvm

我在WPF中有一个ListBox,里面有CheckBox个项目。我在XAML代码隐藏中使用以下代码拆分选中的复选框。

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
}

问题是我不知道如何使用MVVM做到这一点。你会提供一些解决方案吗?

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>

2 个答案:

答案 0 :(得分:3)

使用以下代码:

<强> 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>

<强>代码:

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
    }
}

ViewModel中的任意时间使用上述代码,您将能够从集合Months获取所选项目,并且可以根据需要应用代码。

答案 1 :(得分:2)

以下是使用MVVM执行此操作的方法。

首先,为您的月份创建一个模型( M VVM)。

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

现在,您希望将ViewModel(MV VM )中的内容公开为所有月份的集合。

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

然后在您的视图中绑定它们(M V VM)

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

这就是MVVM 的工作方式