Automatically filter/order ListBox items (Windows Phone)

84 Views Asked by At

I want to ensure, that the items added in my list box are ordered in ascending order according to the serial number of each item (e.g 1 item, 2 item, 4 item, 3 item should be automatically order according to its number 1.2.3.......10).

Here is the C# source:

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);
            }                
        }
    }
}

Here is the XAML code:

    <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>
1

There are 1 best solutions below

2
Martin Zikmund On BEST ANSWER

In the MainPage constructor you have the sort code, but you don't set the content to the list box, which is why it didn't display in sorted order.

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

For the FavoriteButton_Click handler, you have a similar situation - you were sorting and saving the sorted results into a new list, which did not affect the original listobj instance. OrderBy is a LINQ extension which does not affect the original instance, so you can only clear and re-add the items to the original instance manually.

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);

    }
}

Also as a suggestion - you don't have to use MyDataList type, you can directly use ObservableCollection<MyData> everywhere.

Overall advice

As you can see this code is getting quite hard to maintain and keep functional. For that reason I suggest you to read some book on design patterns or Windows app development, especially to learn about MVVM pattern, data-binding and INotifyPropertyChanged. These are quite essential in building maintainable and stable Windows applications.

Also I think it would be helpful to learn some better C# code conventions - for better readability with more consistent variable naming (avoiding things like Settings1, listobj), commenting and code structure. It takes time but the end result is well worth the effort :-) .