簡體   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