自动 filter/order 列表框项目 (Windows Phone)

Automatically filter/order ListBox items (Windows Phone)

我想确保添加到我的列表框中的项目是根据每个项目的序列号按升序排列的(例如 1 项目、2 项目、4 项目、3 项目应该根据它的编号 1.2.3.......10)。

这是 C# 源代码:

namespace XeroQuiz
{

   public partial class MainPage : PhoneApplicationPage
   {
     IsolatedStorageFile Settings1 = IsolatedStorageFile.GetUserStoreForApplication();
     MyDataList listobj = new MyDataList();

     public MainPage()
     {
        InitializeComponent();
        this.Loaded += MainPage_Loaded;
        this.FavoriteListBox.Visibility = Visibility.Collapsed;
        if (Settings1.FileExists("MyStoreItems"))
        {
            using (IsolatedStorageFileStream fileStream = Settings1.OpenFile("MyStoreItems", FileMode.Open))
            {
                DataContractSerializer serializer = new DataContractSerializer(typeof(MyDataList));
                listobj = (MyDataList)serializer.ReadObject(fileStream);

            }
        }
        FavoriteListBox.ItemsSource = listobj;//binding isolated storage list data

        DispatcherTimer timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(0.5) };
        timer.Tick += delegate (object sender, EventArgs e)
        {
            // var sortedList = listobj.OrderBy(item => item.AnswerName).ToList(); code is correct but no item is sorted in list.
            this.FavoriteListBox.ItemsSource = listobj;
            this.FavoriteListBox.UpdateLayout();
        };
        timer.Start();
    }


    /**************************************************************************/

    private void MainPage_Loaded(object sender, RoutedEventArgs e)
    {
        if (Settings1.FileExists("MyStoreItems"))//loaded previous items into list
        {
            using (IsolatedStorageFileStream fileStream = Settings1.OpenFile("MyStoreItems", FileMode.Open))
            {
                DataContractSerializer serializer = new DataContractSerializer(typeof(MyDataList));
                listobj = (MyDataList)serializer.ReadObject(fileStream);
            }
        }
    }


    private void FavoriteButton_Click(object sender, RoutedEventArgs e)
    {
        if (listobj.Any(l => l.AnswerName == AnswerTextBlock.Text))
            return;
        //var sortedList = listobj.OrderBy(item => item.ToString()).ToList();
        listobj.Add(new MyData { AnswerName = AnswerTextBlock.Text });

        using (IsolatedStorageFileStream fileStream = Settings1.OpenFile("MyStoreItems", FileMode.Create))
        {
            DataContractSerializer serializer = new DataContractSerializer(typeof(MyDataList));
            serializer.WriteObject(fileStream, listobj);

        }
    }


    private void FavoriteRemoveButton_Click(object sender, RoutedEventArgs e)
    {
        lsitobj.Remove(listobj.FirstOrDefault(l => l.AnswerName == AnswerTextBlock.Text));

        using (IsolatedStorageFileStream fileStream = Settings1.OpenFile("MyStoreItems", FileMode.Create))
        {
            DataContractSerializer serializer = new DataContractSerializer(typeof(MyDataList));
            serializer.WriteObject(fileStream, listobj);

        }
    }
}



    private void FavoriteListButton_Click(object sender, RoutedEventArgs e)
    {
        if (FavoriteListBox.Visibility.Equals(Visibility.Collapsed))
        {
            FavoriteListBox.Visibility = Visibility.Visible;               
        }
        else if (FavoriteListBox.Visibility.Equals(Visibility.Visible))
        {
            FavoriteListBox.Visibility = Visibility.Collapsed;
        }
    }




    public class MyData
    {
        public string AnswerName { get; set; }
    }
    public class MyDataList : ObservableCollection<MyData>//for storing mydata class items with type of list
    {

    }


    private void FavoriteListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        MyData selecteddata = (sender as ListBox).SelectedItem as MyData;            
        if (selecteddata != null)
        {
            FavoritedData.Text = selecteddata.FrequencyName.ToString();
            using (IsolatedStorageFileStream fileStream = Settings1.OpenFile("MySelectedStoreItem", FileMode.Create))
            {
                DataContractSerializer serializer = new DataContractSerializer(typeof(MyData));
                serializer.WriteObject(fileStream, selecteddata);
            }                
        }
    }
}

这是 XAML 代码:

    <StackPanel Grid.Column="1" Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Top">                
        <ListBox x:Name="FavoriteListBox" Visibility="Collapsed" 
                 SelectionChanged="FavoriteListBox_SelectionChanged"
                 HorizontalAlignment="Stretch"
                 VerticalAlignment="Top" Opacity="1"
                 Background="{StaticResource PhoneBackgroundBrush}" Foreground="{StaticResource PhoneForegroundBrush}"
                 Height="300" Width="250">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock Visibility="Visible" x:Name="FavoriteListBoxTextBlock"  
                               FontSize="35" Foreground="Black" Text="{Binding AnswerName}"/>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </StackPanel>

<StackPanel Grid.Row="0" Grid.Column= "0" HorizontalAlignment= "Left" VerticalAlignment= "Top" >
< Button x:Name= "FavoriteButton" FontFamily= "Segoe MDL2 Assets"
        Content= "&#xE006;" BorderBrush= "Transparent" FontSize= "28"
        Foreground= "{StaticResource PhoneForegroundBrush}"
        Style= "{StaticResource ButtonStyle1}" Click= "FavoriteButton_Click" />
</ StackPanel >

<StackPanel Grid.Row="0" Grid.Column= "2" HorizontalAlignment= "Left" VerticalAlignment= "Top" >
< Button x:Name= "FavoriteListButton" FontFamily= "Segoe MDL2 Assets"
        Content= "&#xEA55;" BorderBrush= "Transparent" FontSize= "28"
        Foreground= "{StaticResource PhoneForegroundBrush}"
        Style= "{StaticResource ButtonStyle1}" Click= "FavoriteListButton_Click" />
</StackPanel>

MainPage 构造函数中有排序代码,但没有将内容设置到列表框中,这就是它没有按排序顺序显示的原因。

var sortedList = listobj.OrderBy(item => item.AnswerName).ToList();
this.FavoriteListBox.ItemsSource = sortedList; //you were using listobj, which isn't sorted

对于 FavoriteButton_Click 处理程序,您有类似的情况 - 您正在排序并将排序结果保存到新列表中,这不会影响原始 listobj 实例。 OrderBy是一个LINQ扩展,不影响原实例,所以你只能手动清除并重新添加项目到原实例。

private void FavoriteButton_Click(object sender, RoutedEventArgs e)
{
    if (listobj.Any(l => l.AnswerName == AnswerTextBlock.Text))
        return;
    //add
    listobj.Add(new MyData { AnswerName = AnswerTextBlock.Text });
    //sort (does not modify the original listobj instance!)
    var sortedList = listobj.OrderBy(item => item.ToString()).ToList();

    //clear and re-add all items in the sorted order
    listobj.Clear();
    foreach( var item in sortedList )
    {
        listobj.Add( item );
    }

    using (IsolatedStorageFileStream fileStream = Settings1.OpenFile("MyStoreItems", FileMode.Create))
    {
        DataContractSerializer serializer = new DataContractSerializer(typeof(MyDataList));
        serializer.WriteObject(fileStream, listobj);

    }
}

另外一个建议——你不必使用MyDataList类型,你可以直接在任何地方使用ObservableCollection<MyData>

总体建议

如您所见,此代码越来越难以维护和保持功能正常。出于这个原因,我建议您阅读一些关于设计模式或 Windows 应用程序开发的书,尤其是了解 MVVM 模式、data-bindingINotifyPropertyChanged。这些对于构建可维护和稳定的 Windows 应用程序非常重要。

此外,我认为学习一些更好的 C# 代码约定会有所帮助 - 通过更一致的变量命名(避免像 Settings1listobj)、注释和代码结构来获得更好的可读性。这需要时间,但最终结果是值得付出努力的:-) .