2016-01-06 6 views
3

У меня есть ListBox, содержащий имена файлов. Теперь мне нужно получить массив выбранных элементов из этого списка. Я нашел здесь несколько ответов, но никто из них не работал для меня. Я использую каркас Caliburn Micro.Множественный выбор в WPF MVVM ListBox

Вот мой Вид:

<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 

} 

ответ

7

Вы можете использовать этот код для 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> 

ViewModel

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"); 
     } 
    } 
} 
+0

Большое спасибо, сэр, это работает отлично! – Michal

0

Вы можете добавить обработчик событий SelectionChanged в код-позади, и обновлять свойство для выбранных элементов в ViewModel оттуда.

XAML:

<ListBox x:Name="DeleteHistoryListBox" SelectedItem="{Binding Path=DeleteHistorySelectedItem}" 
      ItemsSource="{Binding DeleteHistoryListBox, NotifyOnSourceUpdated=True}" 
     SelectionMode="Multiple" SelectionChanged="DeleteHistoryListBox_SelectionChanged"> 
    </ListBox> 

DeleteHistoryView.xaml.cs

private void DeleteHistoryListBox_SelectionChanged(object sender, SelectionChangedEventArgs e) 
{ 
     DeleteHistoryViewModel vm = (DeleteHistoryViewModel)DataContext; 

     foreach (string item in e.AddedItems) 
     { 
      vm.DeleteHistorySelectedItem.Add(item); 
     } 

     foreach (string item in e.RemovedItems) 
     { 
      vm.DeleteHistorySelectedItem.Remove(item); 
     } 
} 
Смежные вопросы