【问题标题】:Multiple selection in WPF MVVM ListBoxWPF MVVM ListBox中的多选
【发布时间】:2016-04-10 09:11:18
【问题描述】:

我有一个包含文件名的 ListBox。现在我需要从这个 ListBox 中获取所选项目的数组。我在这里找到了一些答案,但没有一个对我有用。我正在使用 Caliburn Micro 框架。

这是我的观点:

<Window x:Class="ProgramsAndUpdatesDesktop.Views.DeleteHistoryView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:ProgramsAndUpdatesDesktop.Views"
    mc:Ignorable="d"
    ResizeMode="CanResizeWithGrip"
    MaxWidth="300"
    MinWidth="300"
    MinHeight="500"
    Title="DeleteHistoryView" Height="500" Width="300">
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="30" />
    </Grid.RowDefinitions>
    <StackPanel Grid.Column="0" Grid.Row="0">
        <ListBox x:Name="DeleteHistoryListBox" SelectedItem="{Binding Path=DeleteHistorySelectedItem}" 
                 ItemsSource="{Binding DeleteHistoryListBox, NotifyOnSourceUpdated=True}" 
             SelectionMode="Multiple">
        </ListBox>
    </StackPanel>
    <StackPanel Grid.Column="0" Grid.Row="1">
        <Button x:Name="DeleteHistoryButtonAction">Delete</Button>
    </StackPanel>
</Grid>

这是我的 ViewModel:

class DeleteHistoryViewModel : Screen
{
    string historyFolderPath = Environment.ExpandEnvironmentVariables(ConfigurationManager.AppSettings["HistoryFolderPath"]);

    private ObservableCollection<string> deleteHistoryListBox = new ObservableCollection<string>();
    public ObservableCollection<string> DeleteHistoryListBox
    {
        get { return deleteHistoryListBox; }
        set { deleteHistoryListBox = value; NotifyOfPropertyChange(() => DeleteHistoryListBox); }
    }

    private List<string> deleteHistorySelectedItem = new List<string>();
    public List<string> DeleteHistorySelectedItem
    {
        get { return deleteHistorySelectedItem; }
        set { deleteHistorySelectedItem = value; }
    }

    public DeleteHistoryViewModel()
    {
        base.DisplayName = "Delete History";
    }

    protected override void OnInitialize()
    {
        FillListBox();
    }

    private void FillListBox()
    {
        string[] directory = Directory.GetFiles($"{historyFolderPath}\\", "*.json");

        foreach (var item in directory)
        {
            string fileName = System.IO.Path.GetFileName(item).ToString();
            if (!DeleteHistoryListBox.Contains(fileName))
            {
                DeleteHistoryListBox.Add(fileName);
            }
        }
    }

    #region ACTIONS REGION

    // DELETE HISTORY ACTION
    public void DeleteHistoryButtonAction()
    {
        foreach (var item in DeleteHistorySelectedItem)
        {
            MessageBox.Show(item);
        }
    }

    #endregion

}

【问题讨论】:

    标签: wpf mvvm listbox caliburn.micro multipleselection


    【解决方案1】:

    您可以将此代码用于 MVVM 模式

    XAML

    <ListBox x:Name="DeleteHistoryListBoxItem" SelectedItem="{Binding Path=DeleteHistorySelectedItem,UpdateSourceTrigger=PropertyChanged}" 
             ItemsSource="{Binding DeleteHistoryListBox, NotifyOnSourceUpdated=True}" SelectionMode="Multiple">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Item}"/>
            </DataTemplate>
        </ListBox.ItemTemplate>
        <ListBox.ItemContainerStyle>
            <Style TargetType="{x:Type ListBoxItem}">
                <Setter Property="IsSelected" Value="{Binding Mode=TwoWay, Path=IsSelected}"/>
            </Style>
        </ListBox.ItemContainerStyle>
    </ListBox>
    

    视图模型

    private ObservableCollection<HistoryItems> deleteHistoryListBox = new ObservableCollection<HistoryItems>();
    public ObservableCollection<HistoryItems> DeleteHistoryListBox
    {
        get
        {
            return deleteHistoryListBox;
        }
        set
        {
            deleteHistoryListBox = value;
            this.RaisePropertyChanged("DeleteHistoryListBox");
        }
    }
    
    private HistoryItems deleteHistorySelectedItem;
    public HistoryItems DeleteHistorySelectedItem
    {
        get
        {
            return deleteHistorySelectedItem;
        }
        set
        {
            var selectedItems = DeleteHistoryListBox.Where(x => x.IsSelected).Count();
            this.RaisePropertyChanged("DeleteHistorySelectedItem");
        }
    }
    

    public class HistoryItems : INotifyPropertyChanged
    {
        private string item;
    
        public string Item
        {
            get { return item; }
            set
            {
                item = value;
                this.RaisePropertyChanged("Item");
            }
        }
    
        private bool isSelected;
    
        public bool IsSelected
        {
            get { return isSelected; }
            set
            {
                isSelected = value;
                this.RaisePropertyChanged("IsSelected");
            }
        }
    }
    

    【讨论】:

    • 我面临的问题是,当在 ListBox 中选择第二个项目设置为多选时,不会调用 DeleteHistorySelectedItem,我如何确保在用户在 ListBox 中进行选择时引发此事件?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-01
    • 1970-01-01
    相关资源
    最近更新 更多