删除选择上的ListBoxItem

时间:2016-09-09 09:03:55

标签: c# wpf listbox

我有一个用字符串填充的ListBox(secondListBox)(ToAddToLBFilterStrings)。当用户点击ListBoxItem时,我想从ListBox中删除它。这就是我试图这样做的方式;

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();
    }
}

这不仅仅是移除一个项目,而是有时会删除所有项目,有时候是一组随机的项目,它不会按照我的预期运行。

2 个答案:

答案 0 :(得分:1)

首先,我想开始你是一个完全错误的道路,因为你使用WPF,你必须使用MVVM-Model和DataBindings。我创建了一个示例应用程序,它只执行一项操作:“从列表框中删除单击的项目”。它看起来像这样......

观点:

<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 :(得分:-1)

尝试使用“Observable Collection”类而不是List。它具有内置功能,以通知属性/ ListItem已更改。所以没有必要刷新列表。 Observable collection会自动刷新,UI会立即更新。

使用“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);