如果我选择其他列表框,如何在列表框中设置SeletedItems = null

时间:2013-12-10 11:41:41

标签: c# mvvm listbox

基本上我正在尝试THIS

但你可以看到它不是MVVM所以我正在寻找一种方法来设置SeletedItems = nullclear()取决于可行的方法

因为在我的视图中我会得到N ListBoxes,如果他在选择了一些项目后按了Button我将更改SeletedItems的某些属性,但仅限于最后一个Listbox SelectedItems 1}}

所以我决定在所有Listboxes上使用SelectedItems属性,但是根据我无法绑定到Listboxes的2个问题并且基于此我不起作用无法测试如何从其他 <Window x:Class="Test.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <StackPanel> <ListBox Width="432" Height="67" HorizontalAlignment="Left" VerticalAlignment="Top" SelectionMode="Extended" <!-- SeletedItems="{Binding SelectedListItems}" ??? --> ItemsSource="{Binding Collection1}"> <ListBox.ItemsPanel> <ItemsPanelTemplate> <StackPanel Orientation="Horizontal"/> </ItemsPanelTemplate> </ListBox.ItemsPanel> <ListBox.ItemTemplate> <DataTemplate> <Grid> <TextBlock Text="{Binding MyText}" Background="{Binding MyBackground}"/> </Grid> </DataTemplate> </ListBox.ItemTemplate> </ListBox> <ListBox Width="432" Height="67" HorizontalAlignment="Left" VerticalAlignment="Top" SelectionMode="Extended" <!-- SeletedItems="{Binding SelectedListItems}" ??? --> ItemsSource="{Binding Collection2}"> <ListBox.ItemsPanel> <ItemsPanelTemplate> <StackPanel Orientation="Horizontal"/> </ItemsPanelTemplate> </ListBox.ItemsPanel> <ListBox.ItemTemplate> <DataTemplate> <Grid> <TextBlock Text="{Binding MyText}" Background="{Binding MyBackground}"/> </Grid> </DataTemplate> </ListBox.ItemTemplate> </ListBox> <Button Content="unselect" Width="80" Height="150" HorizontalAlignment="Right" VerticalAlignment="Top" Command="{Binding MyCommand}"/> </StackPanel> </Window>

中删除选择

编辑:

给你一个简单的例子:

XAML

using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;

namespace Test
{
    /// <summary>
    /// Interaktionslogik für MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = new VM();
        }
    }

    public class VM : INotifyPropertyChanged
    {
        private ObservableCollection<DetailVM> _SelectedListItems = new ObservableCollection<DetailVM>();
        public ObservableCollection<DetailVM> SelectedListItems
        {
            get { return _SelectedListItems; }
            set
            {
                _SelectedListItems = value;
                OnPropertyChanged("SelectedListItems");
            }
        }

        public List<DetailVM> Collection1 { get; set; }
        public List<DetailVM> Collection2 { get; set; }

        private RelayCommand _myCommand;
        public ICommand MyCommand
        {
            get { return _myCommand?? (_myCommand= new RelayCommand(param => OnMyCommand())); }
        }
        public void OnMyCommand()
        {
            foreach DetailVM item in SelectedListItems
            {
                item.MyBackground ="Red";
            }
        }

        public VM()
        {
            Collection1 = new List<DetailVM>();
            Collection2 = new List<DetailVM>();

            for (int i = 0; i < 10; i++)
            {
                Collection1.Add(new DetailVM { MyText = "C1ITEM " + i });
                Collection2.Add(new DetailVM { MyText = "C2ITEM " + i });
            }
        }

        #region INotifyPropertyChanged Member

        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion
    }

    public class DetailVM
    {
        public string MyText { get; set; }
        public string MyBackground { get; set; }
    }
}

代码

{{1}}

上面的代码应该将文本框背景的颜色更改为红色
如果用户选择了列表框中的某些项目,他应该只能同时在一个列表框中选择项目

那怎么办呢? (请记住这是一个简单的例子,但我需要这个N Listboxes,它将通过模板生成)

1 个答案:

答案 0 :(得分:1)

首先,我建议您扩展ListView,使其包含可绑定的SelectedValues属性(您不能使用名称SelectedItems,因为它已经是ListView的不可绑定属性)。这是一个如何实现这一目标的例子。

public class MultiSelectListView : ListView
{
// Using a DependencyProperty as backing store
public static readonly DependencyProperty SelectedValuesProperty =
  DependencyProperty.Register("SelectedValues", typeof(IList), typeof(MultiSelectListView), new PropertyMetadata(default(IList), OnSelectedItemsChanged));

public IList SelectedValues
{
  get { return (IList)GetValue(SelectedValuesProperty); }
  set { SetValue(SelectedValuesProperty, value); }
}


private static void OnSelectedItemsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
  // if selected items list implements INotifyCollectionChanged, we subscribe to its CollectionChanged event
  var element = (MultiSelectListView)d;
  if (e.OldValue != null && e.OldValue is INotifyCollectionChanged)
  {
    var list = e.OldValue as INotifyCollectionChanged;
    list.CollectionChanged -= element.OnCollectionChanged;
  }
  if (e.NewValue is INotifyCollectionChanged)
  {
    var list = e.NewValue as INotifyCollectionChanged;
    list.CollectionChanged += element.OnCollectionChanged;
  }

}

// when selection changes in the view, elements are added or removed from the underlying list
protected override void OnSelectionChanged(SelectionChangedEventArgs e)
{
  if (SelectedValues != null)
  {
    foreach (var item in e.AddedItems)
    {
      if (!SelectedValues.Contains(item))
        SelectedValues.Add(item);
    }
    foreach (var item in e.RemovedItems)
    {
      if (SelectedValues.Contains(item))
        SelectedValues.Remove(item);
    }
  }
  base.OnSelectionChanged(e);
}

// when underlying list changes, we set the control's selected items to the contents of the list
void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
  if (SelectedValues != null)
  {
    SetSelectedItems(SelectedValues);
  }
}

}

完成此操作后,您可以通过viewmodel控制列表所选项的行为。清除视图模型列表会清除控件中的选定项目。

接下来,您可以订阅所选项目列表的集合更改事件(在视图模型中),并在处理程序中检查是否需要清除任何列表。