【问题标题】:Filtering ListBox.ItemsSource with CheckBoxes使用 CheckBoxes 过滤 ListBox.ItemsSource
【发布时间】:2014-04-18 09:43:48
【问题描述】:

我是 Windows Phone 编程的新手,在 ListBox 中编辑数据时遇到问题。
我正在将 XML 文件中的数据加载到列表中,并在 ListBox 中显示它们。
我的 XML 中的每个条目都附加了一个类型。我想通过选中/取消选中某些复选框来删除/添加某些类型的条目。

我发现了这样的东西:
How to remove all ListBox items?

但它并不完全适合我的需要,因为我只想删除部分 ListBox 项目,然后可能只需再次选中复选框即可将其取回。
此外,我不想手动添加每个条目,因为我已经将列表框与包含我的 XML 条目的列表绑定。

我像这样上传我的 XML:

Activity.cs:

namespace ReadXMLfromFile
{
   public class Activity
   {
      public string Type { get; private set; }
      public string Description { get; private set; }

      public Activity(string type, string description)
      {
           Type = type;
           Description = description;
      }

      public static List<Activity> LoadActivities(XDocument doc)
      {
        return doc .Root
                   .Elements("Activity")
                   .Select(el => new Activity((string)el.Attribute("Type"),
                                            el.Value))
                   .ToList();
      }

      public static List<Activity> LoadActivities()
      {
        using (var store = IsolatedStorageFile.GetUserStoreForApplication())
        {
            if (store.FileExists("Activities.xml"))
            {
                 using (var stream = store.OpenFile("Activities.xml",
                                                    FileMode.Open))
                 {
                     return LoadActivities(XDocument.Load(stream));
                 }
            }
        }
        // No user file... load the default activities
        return LoadActivities(XDocument.Load("Assets/Activities.xml"));

      }
   }
}

这是我的页面代码:

namespace ActivityManager
{
    public partial class PivotPage1 : PhoneApplicationPage
    {
        private List<Activity> activities;

        public void ActivityDisplay()
        {
            activities = Activity.LoadActivities();
            listBox1.ItemsSource = activities;
        }

        public PivotPage1()
        {
            InitializeComponent();
            ActivityDisplay();
        }

        private void CookingCheck_Checked(object sender, RoutedEventArgs e)
        {
        }

        private void ArtCheck_Checked(object sender, RoutedEventArgs e)
        {
        }

        private void LanguageCheck_Checked(object sender, RoutedEventArgs e)
        {
        }

        private void ScienceCheck_Checked(object sender, RoutedEventArgs e)
        {
        }

        private void SportCheck_Checked(object sender, RoutedEventArgs e)
        {
        }

ListBox 的 xaml:

<ListBox Height="347" HorizontalAlignment="Left" Margin="27,243,0,0" 
         Name="listBox1" VerticalAlignment="Top" Width="410" 
         SelectionChanged="listBox1_SelectionChanged" AllowDrop="False" 
         ItemsSource="{Binding activities}">
     <ListBox.ItemTemplate>
         <DataTemplate>
              <StackPanel Margin="10">
                   <TextBlock Text="{Binding Activity}"/>
              </StackPanel>
         </DataTemplate>
     </ListBox.ItemTemplate>
 </ListBox>

这也是我的 XML 文件

<?xml version="1.0" encoding="utf-8" ?>
<Activities>
    <Activity Type="Cooking">
      Cook some Mexican food
    </Activity>
    <Activity Type="Art">
      Draw a picture
    </Activity>
    <Activity Type="Language">
      Learn 5 words in Polish you didn't know yet
    </Activity>
    <Activity Type="Science">
      Write a simple program in C
    </Activity>
    <Activity Type="Sport">
      Go to the gym
    </Activity>
  </Activities>

你能帮帮我吗?我很困惑,可能错过了一些明显的东西。提前谢谢你。

【问题讨论】:

  • 请在您检查的事件中放置一个断点,并在 FilterActivity Happend 检查 ItemsSource 不为空并且其中包含对象
  • @verdesrobert 结果在检查事件期间源为空。 FilterActivity 发生后,里面终于有对象了。

标签: c# xml windows-phone-7 listbox


【解决方案1】:

你应该这样做:
创建过滤器列表。
选中/取消选中复选框时更新过滤器列表,并在每次过滤器更改时更新列表

private List<Activity> activities;

public void ActivityDisplay()
{
    activities = Activity.LoadActivities();
    FilterActivities();
}

public ObservableCollection<string> ActivityFilter = new ObservableCollection<string>();

private void FilterActivities()
{
    listbox1.ItemsSource = null; //sometimes it makes the difference;
    listBox1.ItemsSource = activities.Where(activity => ActivityFilter.Any(filter => filter == activity.Type) || ActivityFilter.Count == 0);

}

public PivotPage1()
{
    InitializeComponent();
    ActivityFilter.CollectionChanged += ActivityFilter_CollectionChanged;
    ActivityDisplay();
}

void ActivityFilter_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
    FilterActivities();
}

private void CookingCheck_Checked(object sender, RoutedEventArgs e)
{
    ActivityFilter.Add("Cooking");
}

private void CookingCheck_Unchecked(object sender, RoutedEventArgs e)
{
    ActivityFilter.Remove("Cooking");
}

//Repeat the procedure for each checkbox

我在您的 ItemTemplate 中发现了一个问题,请使用这个

 <ListBox.ItemTemplate>
     <DataTemplate>
          <StackPanel Margin="10">
               <TextBlock Text="{Binding Description}"/>
          </StackPanel>
     </DataTemplate>
 </ListBox.ItemTemplate>

【讨论】:

  • 嗨。我尝试使用您的代码并重复该过程,但不幸的是它似乎不起作用。这个是完整的吗?还是有一些其他方法我必须刷新列表框才能正确显示?因为到目前为止,无论我选中/取消选中什么,列表框似乎都不受影响。
  • 遗憾的是它没有解决问题。但是,在再次查看代码后,我注意到您在示例中从 public void ActivityDisplay 中删除了 listBox1.ItemsSource = activities;。当我做同样的事情时,活动列表根本没有加载。会不会是listBox1.ItemsSource = activities.Where(activity =&gt; ActivityFilter.Any(filter =&gt; filter == activity.Type) || ActivityFilter.Count == 0);有问题?
  • @Tajgun92 一开始忘了绑定,检查编辑
  • 现在它再次正确绑定,但遗憾的是我的问题并没有解决。复选框仍然不适用于列表框。改变 ItemTemplate 所做的只是从列表框中删除类型,只留下描述
猜你喜欢
  • 2015-11-14
  • 1970-01-01
  • 1970-01-01
  • 2021-04-09
  • 1970-01-01
  • 2010-12-12
  • 1970-01-01
  • 2011-08-10
  • 2019-03-12
相关资源
最近更新 更多