繁体   English   中英

从 ListBox 中删除项目 - WPF 中未处理的异常?

[英]Removing item from ListBox - unhandled exception in WPF?

我的主窗口中有这段代码。 用户在提供的字段中输入姓名、电话和电子邮件,选择位置,然后姓名出现在列表框 lstClients 中。

在此处输入图像描述

我正在尝试编写一种方法来从列表框中删除选定的名称。

namespace WpfApp_Employment_Help
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        // client list

        List<Client> ClientList = new List<Client>();
        public MainWindow()
        {
            InitializeComponent();
        }

        // method to select location via radio button
        public string GetSelectedLocation()
        {
            string selected = string.Empty;
           if (RBLocE.IsChecked == true) { selected = "Edinburgh"; }
           else if (RBLocG.IsChecked == true) { selected = "Glasgow"; }
           else if (RBLocO.IsChecked == true) { selected = "Other"; }
           
           return selected;
        }


        // method to create a new client on click
        private void newClient(object sender, RoutedEventArgs e)
        {
            Client c = new Client(boxClientName.Text, boxClientPhone.Text, boxClientEmail.Text, GetSelectedLocation());
            boxClientName.Clear();
            boxClientPhone.Clear();
            boxClientEmail.Clear();
            ClientList.Add(c);
            lstClients.ItemsSource = null;
            lstClients.ItemsSource = ClientList;
        }

        // method to id selected client
        private void AssignID(object sender, RoutedEventArgs e)
        {
            Client c = lstClients.SelectedItem as Client;
            if (c != null)
            {
                c.AssignID();
            }
            lstClients.ItemsSource = null;
            lstClients.ItemsSource = ClientList;
        }

        //    method to remove selected client

        private void RemoveClient(object sender, RoutedEventArgs e)
        {
            lstClients.Items.Remove(lstClients.SelectedItem);
        }

             
        
    }
}

当我运行此代码时,出现未处理的异常:System.InvalidOperationException:'在使用 ItemsSource 时操作无效。 改为使用 ItemsControl.ItemsSource 访问和修改元素。 在此处输入图像描述

如何重写我的 RemoveClient 方法? 我的客户端类代码是这样的:

   public partial class Client
     {
        public string Name { get; set; }
        public string Phone { get; set; }
        public string Email { get; set; }

        public string Location { get; }

        public bool IDed { get; private set; }

        public Client(string n, string p, string e, string l)
        {
            Name = n;
            Phone = p;
            Email = e;
            Location = l;

        }
    }

我有最近更新的 Visual Studio 2022。

我也尝试过以下解决方案,但它给了我另一个未处理的错误? 看来我需要将 List </string/> 和 string 更改为其他内容。 但是什么?

        private void RemoveClient(object sender, EventArgs e)
        {
            if (lstClients.Items.Count >= 1)
            {
                if (lstClients.SelectedValue != null)
                {
                    var items = (List<string>)lstClients.ItemsSource;

                    var item = (string)lstClients.SelectedValue;
                    lstClients.ItemsSource = null;
                    lstClients.Items.Clear();
                    items.Remove(item);
                    lstClients.ItemsSource = items;
                }
            }
            else
            {
                System.Windows.Forms.MessageBox.Show("No ITEMS Found");
            }
        }



System.InvalidCastException: 'Unable to cast object of type 'System.Collections.Generic.List`1[WpfApp_Employment_Help.Client]' to type 'System.Collections.Generic.List`1[System.String]'.'

如错误消息所示,您无法通过从ItemsControl.Items属性返回的集合视图修改ItemsControl

WPF 通常设计用于处理数据源,而不是处理与数据相关的控件(数据表示)。 通过这种方式,数据和数据表示 (GUI) 被完全分离,代码编写起来也会简单很多。
对于ListView (或一般的ItemsControl ),只需修改源集合。

为了提高性能,源集合应该是INotifyCollectionChanged实现,例如ObservableCollection<T> ,尤其是当您希望修改源集合时。
这使得ItemsSource无效,例如通过分配null ,只是为了再次设置它是多余的,并显着提高了性能。

public partial class MainWindow : Window
{
  // client list
  public ObservableCollection<Client> ClientList { get; } = new ObservableCollection<Client>();

  // method to create a new client on click
  private void newClient(object sender, RoutedEventArgs e)
  {
    Client c = new Client(boxClientName.Text, boxClientPhone.Text, boxClientEmail.Text, GetSelectedLocation());
    boxClientName.Clear();
    boxClientPhone.Clear();
    boxClientEmail.Clear();
    
    ClientList.Add(c);
    
    // The following lines are no longer needed 
    // as the GUI is now notified about the collection changes (by the INotifyCollectionChanged collection)
    //lstClients.ItemsSource = null;
    //lstClients.ItemsSource = ClientList;
  }

  // method to id selected client
  private void AssignID(object sender, RoutedEventArgs e)
  {
    Client c = lstClients.SelectedItem as Client;
    
    // Same as the if-statement below
    c?.AssignID();
    
    //if (c != null)
    //{
    //  c.AssignID();
    //}
    
    // The following lines are no longer needed 
    // as the GUI is now notified about the collection changes (by the INotifyCollectionChanged collection)
    //lstClients.ItemsSource = null;
    //lstClients.ItemsSource = ClientList;
 }

 // method to remove selected client
 private void RemoveClient(object sender, RoutedEventArgs e)
 {
   var clientToRemove = lstClients.SelectedItem as Client;
   this.ClientList.Remove(clientToRemove);
 }
}

如果将ClientList的类型从List<Client>更改为ObservableCollection<Client> ,您只需直接从源集合中删除该项目:

public partial class MainWindow : Window
{
    ObservableCollection<Client> ClientList = new ObservableCollection<Client>();
    public MainWindow()
    {
        InitializeComponent();
    }

    ...
    private void RemoveClient(object sender, RoutedEventArgs e)
    {
        ClientList.Remove(lstClients.SelectedItem as Client);
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM