Remove an item from listbox in WP7

2019-09-17 10:44发布

问题:

I am both a freshman in WP7 and c# development .I confused with listbox removing operate. I want to remove a item through a click event(remove item data and refresh UI).I've searched in website,and knew first resource should extend ObservableCollection, but How to do next?Who can give me a more detail example. Here is my code MainPage.xaml.Example source download

<phone:PhoneApplicationPage x:Class="WPListBoxImage.MainPage"
                            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                            xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
                            xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
                            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
                            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
                            xmlns:data="clr-namespace:WPListBoxImage"
                            mc:Ignorable="d"
                            d:DesignWidth="480"
                            d:DesignHeight="768"
                            FontFamily="{StaticResource PhoneFontFamilyNormal}"
                            FontSize="{StaticResource PhoneFontSizeNormal}"
                            Foreground="{StaticResource PhoneForegroundBrush}"
                            SupportedOrientations="Portrait"
                            Orientation="Portrait"
                            shell:SystemTray.IsVisible="True">
  <phone:PhoneApplicationPage.Resources>
    <data:Products x:Key="productCollection" />
    <data:PriceConverter x:Key="priceConvert" />
  </phone:PhoneApplicationPage.Resources>
  <!--LayoutRoot is the root grid where all page content is placed-->
  <Grid x:Name="LayoutRoot"
        Background="Transparent">
    <Grid.RowDefinitions>
      <RowDefinition Height="Auto" />
      <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <!--TitlePanel contains the name of the application and page title-->
    <StackPanel x:Name="TitlePanel"
                Grid.Row="0"
                Margin="12,17,0,28">
      <TextBlock x:Name="ApplicationTitle"
                 Text="PDSA"
                 Style="{StaticResource PhoneTextNormalStyle}" />
      <TextBlock x:Name="PageTitle"
                 Text="Products"
                 Margin="9,-7,0,0"
                 Style="{StaticResource PhoneTextTitle1Style}" />
    </StackPanel>
    <!--ContentPanel - place additional content here-->
    <Grid x:Name="ContentPanel"
          Grid.Row="1"
          Margin="12,0,12,0">
      <ListBox x:Name="lstData"
               ItemsSource="{Binding Source={StaticResource productCollection}, Path=DataCollection}" SelectionChanged="lstData_SelectionChanged">
        <ListBox.ItemTemplate>
          <DataTemplate>
            <StackPanel Orientation="Horizontal">
              <Image Margin="8"
                     VerticalAlignment="Top"
                     Source="{Binding Path=ImageUri}"
                     Width="100"
                     Height="100" />
              <StackPanel>
                <TextBlock Margin="8"
                           Width="250"
                           TextWrapping="Wrap"
                           VerticalAlignment="Top"
                           HorizontalAlignment="Left"
                           Text="{Binding Path=ProductName}" />
                <TextBlock Width="100"
                           Margin="8,0,8,8"
                           VerticalAlignment="Top"
                           HorizontalAlignment="Left"
                           Text="{Binding Path=Price, Converter={StaticResource priceConvert}}" />
              </StackPanel>
            </StackPanel>
          </DataTemplate>
        </ListBox.ItemTemplate>
      </ListBox>
    </Grid>
  </Grid>
</phone:PhoneApplicationPage>

MainPage.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;

namespace WPListBoxImage
{
  public partial class MainPage : PhoneApplicationPage
  {
    // Constructor
    public MainPage()
    {
      InitializeComponent();
    }

    private void lstData_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {

        ListBoxItem lbi = ((sender as ListBox).SelectedItem as ListBoxItem);
      //delete a item,what should to do next?
    }
  }
}

Products.cs

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;

namespace WPListBoxImage
{
    //a ObservableCollection<T>, 
    public class Products : ObservableCollection<Product>
  {
    public Products()
    {
        DataCollection = new ObservableCollection<Product>();
      BuildCollection();
    }

    private const string IMG_PATH = "../Images/";

    public ObservableCollection<Product> DataCollection { get; set; }

    public ObservableCollection<Product> BuildCollection()
    {
      //DataCollection = new ObservableCollection<Product>();

      DataCollection.Add(new Product("Haystack Code Generator for .NET", 799, IMG_PATH + "Haystack.jpg"));
      DataCollection.Add(new Product("Fundamentals of N-Tier eBook", Convert.ToDecimal(19.95), IMG_PATH + "FundNTier_100.jpg"));
      DataCollection.Add(new Product("Fundamentals of ASP.NET Security eBook", Convert.ToDecimal(19.95), IMG_PATH + "FundSecurity_100.jpg"));
      DataCollection.Add(new Product("Fundamentals of SQL Server eBook", Convert.ToDecimal(19.95), IMG_PATH + "FundSQL_100.jpg"));
      DataCollection.Add(new Product("Fundamentals of VB.NET eBook", Convert.ToDecimal(19.95), IMG_PATH + "FundVBNet_100.jpg"));
      DataCollection.Add(new Product("Fundamentals of .NET eBook", Convert.ToDecimal(19.95), IMG_PATH + "FundDotNet_100.jpg"));
      DataCollection.Add(new Product("Architecting ASP.NET eBook", Convert.ToDecimal(19.95), IMG_PATH + "ArchASPNET_100.jpg"));
      DataCollection.Add(new Product("PDSA .NET Productivity Framework", Convert.ToDecimal(2500), IMG_PATH + "framework.jpg"));

      return DataCollection;
    }

  }
}

Product.cs

using System;

namespace WPListBoxImage
{
  public class Product
  {
    #region Constructors

    public Product()
    {
    }

    public Product(string name, decimal price, string imageUri)
    {
      this.ProductName = name;
      this.Price = price;
      this.ImageUri = imageUri;
    }
    #endregion

    public string ProductName { get; set; }
    public decimal Price { get; set; }
    public string ImageUri { get; set; }
  }
}

Here is app screenshot.

thank's for your patience.

回答1:

Your Products class shouldn't inherit anything.

public class Products

Accessing all the items in your collection is done through the DataCollection property of the Product class. For example,

   Products myProducts = new Products();
   ObservableCollection<Product> myData = myProducts.DataCollection;

It also depends on how you want to use Products. You may be able to totally do away with this class and then do something like:

   ObservableCollection<Product> Products = new ObservableCollection<Product>();
    Products.Add(new Product("Haystack Code Generator for .NET", 799, IMG_PATH + "Haystack.jpg"));
    // etc...


回答2:

Firstly you need to obtain a reference to your product collection:

Products productCollection = this.Resources["productCollection"] as Products;

Then find the item that was clicked, this will be the DataContext of the ListBoxItem:

ListBoxItem lbi = ((sender as ListBox).SelectedItem as ListBoxItem);
Product product = lbi.DataContext as Product;

(although, I think that as your listbox is databound, the SelectedItem should be a Product instance. You can check this yourself in the debugger)

Then simply remove it, the ObservableCollection will ensure that the UI is updated:

productCollection.Remove(product);