2015-03-10 8 views
0

У меня есть элементы, привязанные к списку, и я реализовал функцию для их удаления, когда они выбраны, и пользователь нажимает клавишу «Удалить». В настоящее время функция удаления напрямую обращается к источнику. Однако я не хочу изменять источник, если пользователь сначала не нажимает кнопку сохранения.Удалить связанные элементы из списка только при нажатии кнопки сохранения пользователя

Как я могу изменить удаление ListBoxItems, чтобы мой источник не обновлялся, пока пользователь не нажмет кнопку?

Список I связываются с

public ObservableCollection<Process> Processes { get; set; } 

функция удаления

private void OnDeletePressed(object sender, KeyEventArgs e) 
{ 
    if (e.Key == Key.Delete) 
    { 
     foreach (Process item in ProcessListBox.SelectedItems.OfType<Process>().ToList()) 
     { 
      SelectedRobot.Processes.Remove(item); 
     } 
    } 
} 

XAML

<ListBox x:Name="ProcessListBox" ItemsSource="{Binding Processes, UpdateSourceTrigger=Explicit}" KeyDown="OnDeletePressed"> 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <Label Content="{Binding ProcessName}" /> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 
+2

Возможно, у вас есть свойство объекта Process с именем IsDeleted и установлено значение true, когда пользователь нажимает кнопку «Удалить», а затем удаляет элемент из списка, когда пользователь нажимает кнопку «Сохранить»? – Krishna

+1

В дополнение к комментарию от @Krishna вы можете добавить триггер данных к шаблону элемента, который (на основе свойства 'IsDeleted', установленного на' true') устанавливает видимость элемента 'Collapsed' и устанавливает родительский ** ListBoxItem ** свойство 'Focusable' для' false'. Таким образом, элемент «исчезнет» из представления, но все равно будет находиться в списке источников. –

+0

@StevenRands Другим способом будет привязка к ICollectionView и фильтр на IsDeleted. Таким образом, элемент будет удален из коллекции пользовательского интерфейса, но все равно будет присутствовать в исходной коллекции :) – Krishna

ответ

0

Одним из вариантов было бы создать копию вашей коллекции и сохранить оригинал. Например, где-то в инициализации, звоните:

List<Process> pOriginalList = null; 

    pOriginalList = Processes.ToList(); 



    private void OnDeletePressed(object sender, KeyEventArgs e) 
    { 
     if (e.Key == Key.Delete) 
     { 
      foreach (Process item in ProcessListBox.SelectedItems.OfType<Process>().ToList()) 
      { 
       this.Processes.Remove(item); 
      } 
     } 
    } 

    private void OnSaveClick(object sender, RoutedEventArgs e) 
    { 
     // do nothing -- Processes already is set 
    } 

    private void OnCancelClick(object sender, RoutedEventArgs e) 
    { 
     Processes.Clear(); 
     Processes = new ObservableCollection<Process>(pOriginalList); 
     this.DataContext = null; 
     this.DataContext = this; 
    } 

XAML:

<Window x:Class="ListCopy.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"> 
    <Grid> 
     <StackPanel> 
      <StackPanel> 
      <Button Content="Save" Click="OnSaveClick" /> 
       <Button Content="Cancel" Click="OnCancelClick" /> 
      </StackPanel> 
      <ListBox x:Name="ProcessListBox" ItemsSource="{Binding Processes, UpdateSourceTrigger=Explicit}" KeyDown="OnDeletePressed"> 
      <ListBox.ItemTemplate> 
       <DataTemplate> 
        <Label Content="{Binding ProcessName}" /> 
       </DataTemplate> 
      </ListBox.ItemTemplate> 
     </ListBox> 
     </StackPanel> 
    </Grid> 
</Window> 

Это делает операцию явного, чтобы, когда вам требуется фактическое обновление источника. Примечание. Установка DataContext, как это не рекомендуется, просто сделала это, чтобы обеспечить обновление списка в Cancel.

+0

Хотелось бы избежать копирования и перезаписи. Похоже, должно быть возможно внести изменения, которые не применяются к источнику до тех пор, пока не будет запущен UpdateSourceTrigger, как и свойство textbox. – Brandon

+0

Да, для больших списков я мог видеть мотивацию для этого. Если вы попытаетесь удалить ListBox.Items с выбранным индексом, он будет генерировать исключение: {«Операция недействительна при использовании ItemsSource. Доступ и изменение элементов с помощью ItemsControl.ItemsSource вместо.»}, Который указывает на ваш источник привязки (ItemsSource = Процессы). Не уверен в том, как это сделать, не делая копии. –

+0

Если вы хотите, чтобы фактический элемент исчез из списка, сохраните как есть, но создайте еще один список (removeList) и добавьте элемент в этот список перед его удалением. Если вы нажмете «Сохранить», сохраните «Процессы как есть», в противном случае добавьте элементы from deletedList обратно в «Процессы». Это позволяет избежать полной копии. Использование метода, предложенного Кришной, потребовало бы больше работы по удалению (коллапсу) элемента в списке, но также обеспечило бы способ создания пользовательского элемента управления, который автоматически задерживал бы обновление источника. –