问题描述
我想确保添加到我的列表框中的项目按照每个项目的序列号升序排列(例如 1 项目、2 项目、4 项目、3 项目应该根据其编号自动排序1.2.3.......10).
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).
这里是 C# 源代码:
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);
}
}
}
}
这里是 XAML 代码:
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= "" 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= "" BorderBrush= "Transparent" FontSize= "28"
Foreground= "{StaticResource PhoneForegroundBrush}"
Style= "{StaticResource ButtonStyle1}" Click= "FavoriteListButton_Click" />
</StackPanel>
推荐答案
在 MainPage
构造函数中你有排序代码,但你没有将内容设置到列表框,这就是为什么它没有按排序顺序显示.
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
对于 FavoriteButton_Click
处理程序,您有类似的情况 - 您正在对排序后的结果进行排序并将其保存到一个新列表中,这不会影响原始 listobj
实例.OrderBy
是一个不影响原实例的 LINQ 扩展,所以你只能手动清除和重新添加项目到原实例.
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);
}
}
另外作为一个建议——你不必使用 MyDataList
类型,你可以在任何地方直接使用 ObservableCollection
.
Also as a suggestion - you don't have to use MyDataList
type, you can directly use ObservableCollection<MyData>
everywhere.
正如您所见,这段代码越来越难以维护和保持功能.出于这个原因,我建议您阅读一些有关设计模式或 Windows 应用程序开发的书,尤其是了解 MVVM 模式、数据绑定 和 INotifyPropertyChanged.这些对于构建可维护和稳定的 Windows 应用程序非常重要.
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.
另外,我认为学习一些更好的 C# 代码约定会有所帮助 - 通过更一致的变量命名(避免像 Settings1
、listobj
之类的东西)、注释来获得更好的可读性和代码结构.这需要时间,但最终结果值得付出努力:-).
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 :-) .
这篇关于自动过滤/排序 ListBox 项目 (Windows Phone)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!