WPF列表过滤

时间:2011-05-05 08:58:25

标签: c# wpf

我是WPF的新手,所以这可能是一个简单的问题。我有一个应用程序,它从csv文件中读取一些单词并将它们存储在字符串列表中。我想要做的是参数化这个列表,以显示我的列表中最流行的单词。所以在我的UI中我想要一个文本框,当我输入一个例如5将过滤原始列表,仅在新列表中留下5个最受欢迎(频繁)的单词。任何人都可以协助这最后一步吗?谢谢 -

public class VM
{
    public VM()
    {
        Words = LoadWords(fileList);
    }

    public IEnumerable<string> Words { get; private set; }

    string[] fileList = Directory.GetFiles(@"Z:\My Documents\", "*.csv");


    private static IEnumerable<string> LoadWords(String[] fileList)
    {

        List<String> words = new List<String>();
        //
        if (fileList.Length == 1)
        {

            try
            {
                foreach (String line in File.ReadAllLines(fileList[0]))
                {
                    string[] rows = line.Split(',');

                    words.AddRange(rows);
                }

            }
            catch (Exception ex)
            {
                System.Windows.MessageBox.Show(ex.Message, "Problem!");
            }

        }

        else
        {
            System.Windows.MessageBox.Show("Please ensure that you have ONE read file in the source folder.", "Problem!");

        }
        return words;
    }

}

4 个答案:

答案 0 :(得分:1)

LINQ查询按字和按顺序按该字降序的计数进行分组应该这样做。试试这个

private static IEnumerable<string> GetTopWords(int Count)
{
    var popularWords = (from w in words                
          group w by w
          into grp
          orderby grp.Count() descending
          select grp.Key).Take(Count).ToList();
    return popularWords;
}

答案 1 :(得分:1)

您可以使用CollectionViewSource.GetDefaultView(viewModel.Words),它会返回ICollectionView

ICollectionView公开Filter类型的Predicate<object>属性,您可以参与过滤。

所以常见的情况如下:

  1. ViewModel公开属性PopularCount,它绑定到View中的某个文本框。
  2. ViewModel侦听PopularCount属性的变化。
  3. 当出现通知时,model获取viewModel.Words集合的ICollectionView并设置Filter属性。
  4. 您可以找到过滤器属性使用here的工作示例。如果您遇到代码,请告诉我。

答案 2 :(得分:0)

我不确定“单词”列表的分组和排序是否符合您的要求,但如果是,这可能是一种方法:

    int topN = 3;
    List<string> topNWords = new List<string>();

    string[] words = new string[] {
        "word5",
        "word1",
        "word1",
        "word1",
        "word2",
        "word2",
        "word2",
        "word3",
        "word3",
        "word4",
        "word5",
        "word6",
    };

    // [linq query][1] 
    var wordGroups = from s in words
                       group s by s into g
                       select new { Count = g.Count(), Word = g.Key };

    for (int i = 0; i < Math.Min(topN, wordGroups.Count()); i++)
    {
        // (g) => g.Count is a [lambda expression][2]
        // .OrderBy and Reverse are IEnumerable extension methods
        var element = wordGroups.OrderBy((g) => g.Count).Reverse().ElementAt(i);
        topNWords.Add(element.Count + " - " + element.Word);
    }

通过在linq select子句中使用排序可以缩短Thsi,但我也希望向您介绍内联lambdas和可扩展的扩展。

简短版可以是:

topNWords = (from s in words                
          group s by s
          into g
          orderby g.Count() descending
          select g.Key).Take(Math.Min(topN, g.Count()).ToList();

答案 3 :(得分:0)

不是将所有单词都读入列表然后根据频率对其进行排序,而是采用更简洁的方法创建一个存储单词和频率的自定义类MyWord。在读取文件时,可以增加单词的频率。该课程可以实施IComparable<T>来根据频率比较单词。

public class MyWord : IComparable<MyWord>
{
    public MyWord(string word)
    {
        this.Word = word;
        this.Frequency = 0;
    }

    public MyWord(string word, int frequency)
    {
        this.Word = word;
        this.Frequency = frequency;
    }

    public string Word { get; private set;}        
    public int Frequency { get; private set;}

    public void IncrementFrequency()
    {
        this.Frequency++;
    }

    public void DecrementFrequency()
    {
        this.Frequency--;
    }

    public int CompareTo(MyWord secondWord)
    {
        return this.Frequency.CompareTo(secondWord.Frequency);
    }
}

主班VM会有这些成员,

public IEnumerable<MyWord> Words { get; private set; }

private void ShowMostPopularWords(int numberOfWords)
{
    SortMyWordsDescending();
    listBox1.Items.Clear();

    for (int i = 0; i < numberOfWords; i++ )
    {
        listBox1.Items.Add(this.Words.ElementAt(i).Word + "|" + this.Words.ElementAt(i).Frequency);
    }
}

致电ShowMostPopularWords()

private void Button_Click(object sender, RoutedEventArgs e)
{
    int numberOfWords;
    if(Int32.TryParse(textBox1.Text, NumberStyles.Integer, CultureInfo.CurrentUICulture, out numberOfWords))
    {
        ShowMostPopularWords(numberOfWords);
    }
}