2016-09-09 9 views
0

У меня есть ListBox (второйListBox), который заполняется строками (ToAddToLBFilterStrings). Когда пользователь нажимает на ListBoxItem, я хочу удалить его из ListBox. Вот как я пытаюсь это сделать;Удалить ListBoxItem при выборе

private void OnAddToFilterLBSelectionChanged(object sender, SelectionChangedEventArgs e) 
{ 
    var _selectedString = secondListBox.SelectedItem as string; 
    if (!string.IsNullOrEmpty(_selectedString)) 
    { 
     if (_selectedString == "Current") 
     { 
      currentItem.Visibility = Visibility.Visible; 
     } 
     if (_selectedString == "Subcontractors") 
     { 
      subbieItem.Visibility = Visibility.Visible; 
     } 
     if (_selectedString == "Suppliers") 
     { 
      suppliersItem.Visibility = Visibility.Visible; 
     } 
     if (_selectedString == "Plant Hire") 
     { 
      plantHireItem.Visibility = Visibility.Visible; 
     } 
     if (_selectedString == "Architects") 
     { 
      architectsItem.Visibility = Visibility.Visible; 
     } 
     if (_selectedString == "QS") 
     { 
      qsItem.Visibility = Visibility.Visible; 
     } 
     if (_selectedString == "Project Managers") 
     { 
      projectManagerItem.Visibility = Visibility.Visible; 
     } 
     if (_selectedString == "Structural Engineers") 
     { 
      structEngItem.Visibility = Visibility.Visible; 
     } 
     if (_selectedString == "Service Engineers") 
     { 
      servEngItem.Visibility = Visibility.Visible; 
     } 

     ToAddToLBFilterStrings.Remove(_selectedString); 
     secondListBox.Items.Refresh(); 
    } 
} 

Вместо того, чтобы просто удаляя один элемент, это иногда удаляет все элементы, иногда случайную группу элементов, она не работает, как я бы ожидать, что она.

+0

Вы пытались заменить операторы single if операторами if-else-if? –

+0

@UmairFarooq У меня, к сожалению, нет разницы :( – CBreeze

ответ

1

Прежде всего, я хочу начать, что вы на совершенно неправильный путь, потому что, так как вы используете WPF, вы должны использовать MVVM-модели и DataBindings. Я создал пример приложения, которое делает только одно: «удалить щелкнутый элемент из списка». И это выглядит так ...

The View:

<Window x:Class="Test.MainWindow" 
     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:Test" 
     mc:Ignorable="d" 
     Title="MainWindow" Height="350" Width="525" 
     xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 
     > 
    <Window.DataContext> 
     <local:MainViewModel /> 
    </Window.DataContext> 

    <Grid> 
     <ListBox ItemsSource="{Binding Names}" SelectedItem="{Binding SelectedName}"> 
      <i:Interaction.Triggers> 
       <i:EventTrigger EventName="SelectionChanged"> 
        <i:InvokeCommandAction Command="{Binding ListItemClickCommand}" /> 
       </i:EventTrigger> 
      </i:Interaction.Triggers> 
     </ListBox> 
    </Grid> 
</Window> 

ViewModel:

public class MainViewModel : BaseViewModel 
{ 
    public ObservableCollection<string> Names { get; set; } = new ObservableCollection<string>() {"A", "B", "C"}; 

    #region SelectedName 

    private string selectedName; 

    public string SelectedName 
    { 
     get 
     { 
      return selectedName; 
     } 
     set 
     { 
      if (value != selectedName) 
      { 
       selectedName = value; 
       NotifyPropertyChanged(); 
      } 
     } 
    } 

    #endregion 

    #region ListItemClickCommand 

    private ICommand listItemClickCommand; 

    public ICommand ListItemClickCommand 
    { 
     get 
     { 
      if (listItemClickCommand == null) 
      { 
       listItemClickCommand = new RelayCommand(OnListItemClick); 
      } 

      return listItemClickCommand; 
     } 
    } 

    void OnListItemClick(object param) 
    { 
     Names.Remove(SelectedName); 
    } 

    #endregion 
} 

BaseViewModel:

public abstract class BaseViewModel : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    protected virtual void NotifyPropertyChanged([CallerMemberName] string propertyName = null) 
    { 
     PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 

Класс RelayCommand:

public class RelayCommand : ICommand 
{ 
    #region Fields 

    readonly Action<object> _execute; 
    readonly Predicate<object> _canExecute; 

    #endregion // Fields 

    #region Constructors 

    /// <summary> 
    /// Creates a new command that can always execute. 
    /// </summary> 
    /// <param name="execute">The execution logic.</param> 
    public RelayCommand(Action<object> execute) 
     : this(execute, null) 
    { 
    } 

    /// <summary> 
    /// Creates a new command. 
    /// </summary> 
    /// <param name="execute">The execution logic.</param> 
    /// <param name="canExecute">The execution status logic.</param> 
    public RelayCommand(Action<object> execute, Predicate<object> canExecute) 
    { 
     if (execute == null) 
      throw new ArgumentNullException("execute"); 

     _execute = execute; 
     _canExecute = canExecute; 
    } 

    #endregion // Constructors 

    #region ICommand Members 

    [DebuggerStepThrough] 
    public bool CanExecute(object parameter) 
    { 
     return _canExecute == null ? true : _canExecute(parameter); 
    } 

    public event EventHandler CanExecuteChanged 
    { 
     add { CommandManager.RequerySuggested += value; } 
     remove { CommandManager.RequerySuggested -= value; } 
    } 

    public void Execute(object parameter) 
    { 
     _execute(parameter); 
    } 

    #endregion // ICommand Members 
} 

Как вы видите, кода нет кода, и вид и режим просмотра полностью отделены друг от друга.

Замечание: для использования взаимодействий Blend вам необходимо добавить «System.Windows.Interactivity» в «Ссылки».

Все. И в вашем случае из-за изменений Видимости. Вы можете использовать снова тот же шаблон, чтобы вы могли связывать логические значения с видимостью (вам нужен конвертер)

+1

Хотя ответ хороший, но я прошу различить ваше утверждение «потому что, поскольку вы используете WPF, вам нужно использовать MVVM-Model и DataBindings». MVVM дает много Хорошие функции, но Data Bindings также можно использовать без него. Его следует использовать для лучшей ремонтопригодности и масштабируемости, но приложение WPF может выжить без MVVM, а не для кислорода для WPF. Это больше похоже на что-то другое. Выживание возможно с или без него , –

-1

Попробуйте использовать класс «Наблюдаемая коллекция» вместо списка. Он имеет встроенную функциональность для уведомления о том, что свойство/ListItem изменено. Поэтому нет необходимости обновлять список. Наблюдаемая коллекция обновляется автоматически, и пользовательский интерфейс мгновенно обновляется.

Используйте «elseIf» вместо использования нескольких операторов «if».

И удалите элемент из списка, когда он входит в оператор if.

пример:

declaration: 
// declare the List like this.. 

    ObservableCollection<string> ToAddToLBFilterStrings = new ObservableCollection<string>(); 


    if (_selectedString == "Project Managers") 
      { 
       projectManagerItem.Visibility = Visibility.Visible; 

      } 
      elseif (_selectedString == "Structural Engineers") 
      { 
       structEngItem.Visibility = Visibility.Visible; 
      } 
      elseif (_selectedString == "Service Engineers") 
      { 
       servEngItem.Visibility = Visibility.Visible; 
      } 

     // Remove your Item here. And the List will be refreshed Automatically 

       ToAddToLBFilterStrings.Remove(_selectedString); 
Смежные вопросы