在ListBox中获取选中的项目

时间:2015-03-23 23:00:13

标签: c# .net wpf xaml listbox

我将列表框设置为多选模式。选中后," IsChecked" " StuffList"的每个项目中的属性;变化。但是,我无法使用此方法获取在列表框中选择的项目列表。没有" SelectedItems"要在列表框中绑定,只有" SelectedItem"。

如何使用下面的代码获取所选项目?

<ListBox ItemsSource="{Binding BindStuffList}" SelectedItem="{Binding SelectedStuff, Mode=TwoWay}" SelectionMode="Multiple">
  <ListBox.ItemTemplate>
    <DataTemplate>
      <CheckBox IsChecked="{Binding IsChecked, Mode=TwoWay}" Content="{Binding ID}" Margin="2"/>
    </DataTemplate>
  </ListBox.ItemTemplate>

  <ListBox.ItemContainerStyle>
    <Style TargetType="{x:Type ListBoxItem}">
      <Setter Property="IsSelected" Value="{Binding Mode=TwoWay, Path=IsChecked}"/>
    </Style>
  </ListBox.ItemContainerStyle>
</ListBox>

2 个答案:

答案 0 :(得分:0)

好的,我已经创建了一个简单的基于MVVM模式的解决方案。

我的ViewModel

public class MainWindowViewModel : INotifyPropertyChanged
{
    public IList SelectedList
    {
        get { return _selectedList; }
        set
        {
            _selectedList = value;
        }
    }
    private IList _selectedList;
    private List<StringValues> _bindStuffList;
    private object _lock = new object();

    public IEnumerable<StringValues> BindStuffList
    {
        get { return _bindStuffList; }
    }

    public MainWindowViewModel()
    {
        _bindStuffList = new List<StringValues>();
        BindingOperations.EnableCollectionSynchronization(_bindStuffList, _lock);
        BuildStuff();
    }

    private async void BuildStuff()
    {
        await Task.Run(() =>
        {
            for (int i = 0; i < 15; i++)
            {
                _bindStuffList.Add(new StringValues { ID = "Item " + i });
            }
        });

        RaisePropertyChanged("BindStuffList");
    }


    public event PropertyChangedEventHandler PropertyChanged;

    public void RaisePropertyChanged(string propertyName)
    {
        var pc = PropertyChanged;
        if (pc != null)
            pc(this, new PropertyChangedEventArgs(propertyName));
    }
}

StringValues是一个简单的类

public class StringValues
{
    public string ID { get; set; }
    public bool IsChecked { get; set; }
}

我没有使用经典ListBox,而是使用了自定义

public class CustomListBox : ListBox
{
    public CustomListBox()
    {
        this.SelectionChanged += CustomListBox_SelectionChanged;
    }

    void CustomListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        this.SelectedItemsList = this.SelectedItems;
    }

    public IList SelectedItemsList
    {
        get { return (IList)GetValue(SelectedItemsListProperty); }
        set { SetValue(SelectedItemsListProperty, value); }
    }

    public static readonly DependencyProperty SelectedItemsListProperty =
            DependencyProperty.Register("SelectedItemsList", typeof(IList), typeof(CustomListBox));
}

我只是在View

中使用了这个
<Window x:Class="StackOverflow.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:custom ="clr-namespace:StackOverflow"
        Title="MainWindow" Height="350" Width="525">
    <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
        <StackPanel>
            <custom:CustomListBox ItemsSource="{Binding BindStuffList}"
                                  SelectedItem="{Binding SelectedStuff, Mode=TwoWay}"
                                  SelectionMode="Multiple" SelectedItemsList="{Binding SelectedList,Mode=TwoWay}">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <CheckBox IsChecked="{Binding IsChecked, Mode=TwoWay}" Content="{Binding ID}" Margin="2"/>
                    </DataTemplate>
                </ListBox.ItemTemplate>
                <ListBox.ItemContainerStyle>
                    <Style TargetType="{x:Type ListBoxItem}">
                        <Setter Property="IsSelected" Value="{Binding Mode=TwoWay, Path=IsChecked}"/>
                    </Style>
                </ListBox.ItemContainerStyle>
            </custom:CustomListBox>
        </StackPanel>
    </ScrollViewer>
</Window>

SelectedList将始终保留从UI中选择的所有值。如果您愿意,可以删除CheckBox中的DataTemplate因为它是还原剂。

答案 1 :(得分:0)

要获取当前列表中的选定项目,您必须将ItemsSource BindStuffList更改为yourListBox.SelectedItems;

这样,列表的ItemsSource将更新,仅包含选定的项目;

我做了一个例子。

创建了两个ListBox

从FirstList中选择的多个项目和在Second List

中显示的SelectedItems
<ListBox     x:Name="firstList"
             ItemsSource="{Binding MyCollection}"
             SelectionChanged="ListBox_SelectionChanged"
             SelectionMode="Multiple">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <CheckBox IsChecked="{Binding checked, Mode=TwoWay}"></CheckBox>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
    <ListBox x:Name="secondList" ItemsSource={Binding SecondListCollection}/>



private ObservableCollection<abc> myCollection;

    public ObservableCollection<abc> MyCollection
    {
        get { return myCollection; }
        set { myCollection = value; }
    }

    private ObservableCollection<abc> secondListCollection;

    public ObservableCollection<abc> SecondListCollection
    {
        get { return secondListCollection; }
        set { secondListCollection = value; }
    }


    private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        SecondListCollection = (ObservableCollection<abc>)firstList.SelectedItems;
    }