c# - 窗口形式 c# 对房间列表进行排序,这是一个字符串

标签 c# wpf visual-studio-2008 xmpp

我从我们的一位开发人员那里接手了一个项目。

我们有一个窗口表单,用于发送用户有权访问的 openfire 聊天室的字符串。

一些房间被命名为“AAA ROOM 1”和“AAA ROOM 2”等。 如果我使用此代码,它将按“AAA ROOM 1”“AAA ROOM 11”排序,然后在“AAA ROOM 19”之后出现“AAA ROOM 2”

RoomList.BeginUpdate();

foreach (Room r in Rooms) // original room list before getting it sorted
{
    RoomList.Items.Add(r.Name, IsMember(r.ID));
}

RoomList.EndUpdate();

所以我想按正确的顺序(1、2、3、4、5、6、7、8、9、10、11、12)对它进行排序,所以我添加了一些代码来对房间列表及其列表进行排序正确排序,

foreach (Room r in Rooms)
{
    if (r.Name.Contains("AAA") && r.Name.Length <= 7)
                RoomList.Items.Add(r.Name, IsMember(r.ID));
}
foreach (Room r in Rooms)
{
    if (r.Name.Contains("AAA") && r.Name.Length > 7)
        RoomList.Items.Add(r.Name, IsMember(r.ID));
}
foreach (Room r in Rooms)
{
    if (!r.Name.Contains("AAA"))
        RoomList.Items.Add(r.Name, IsMember(r.ID));
}

但是当我保存数据时,它会在此处使用此代码,但不会标记正确的房间。 这是它用来保存成员(member)资格的代码(如果我勾选添加“AAA Room 11”,那么它实际上将其保存为“AAA Room 18”)。

MasterRecord.User.Memberships = "";
foreach (object o in RoomList.CheckedIndices)
{
    if (MasterRecord.User.Memberships.Length > 0)
        MasterRecord.User.Memberships += ",";

    MasterRecord.User.Memberships += GetItem(roomsui.StrToInt(o.ToString())).ToString();
}         

请理解我是这个开发的新手,所以我需要一些帮助来了解如何在检索和保存时正确排序。

此外,我希望能够在用户检查某些房间时弹出一个窗口。

最佳答案

在我看来,将此视为决定首先对哪个房间进行排序的长度问题是错误的。如果房间名称的模式是 {ROOM-NAME}_{ROOM_NUMBER},那么就这样对待它。 (尽管我很讨厌这样说,但有时:这可能是正则表达式的工作!)

var unordered = new[] { "CCC ROOM 10", "CCC ROOM 5", "AAA ROOM 1", "AAA ROOM 14", "AAA ROOM 2", "AAA ROOM 10", "AAA ROOM 5", "BBB ROOM 3", "BBB ROOM 12" };

Regex pattern = new Regex(@"^(\D+)(\d+)$");

var ordered = unordered
    .Select(
        r =>
        {
            Match match = pattern.Match(r);
            return new
            {
                Name = r,
                Prefix = match.Groups[1].Value,
                Number = Convert.ToInt32(match.Groups[2].Value)
            };
        }
    )
    .OrderBy(r => r.Prefix)
    .ThenBy(r => r.Number);

foreach (var room in ordered)
{
    Console.WriteLine(room.Name);
}

此代码产生以下输出...

AAA ROOM 1
AAA ROOM 2
AAA ROOM 5
AAA ROOM 10
AAA ROOM 14
BBB ROOM 3
BBB ROOM 12
CCC ROOM 5
CCC ROOM 10

通过这种方法,我们称玫瑰为玫瑰(或者,具体来说,数字的字符串表示形式为数字)。我使用了匿名类型,这样我就不必运行两次匹配。

编辑:我注意到您说的是 Visual Studio 2008,因此您可能没有使用 .NET 4.0。如果不是,那么多行 lambda 可能无法工作(我不记得它是什么时候添加的。)。这是另一种使用两个正则表达式而不使用匿名类型的方法。我不确定我是不是更喜欢这种方式,既然我已经写好了...

var rooms = new[] { "CCC ROOM 10", "CCC ROOM 5", "AAA ROOM 1", "AAA ROOM 14", "AAA ROOM 2", "AAA ROOM 10", "AAA ROOM 5", "BBB ROOM 3", "BBB ROOM 12" };

Regex prefix = new Regex(@"^\D+");
Regex suffix = new Regex(@"\d+$");

var ordered2 = rooms
    .OrderBy(r => prefix.Match(r).Value)
    .ThenBy(r => Convert.ToInt32(suffix.Match(r).Value));

foreach (var room in ordered2)
{
    Console.WriteLine(room);
}

此外,我可能会注意到,此代码中显然没有出现无法匹配名称的意外情况。如果这是可能的,那将需要内置。

最后,既然您说您是开发新手,那么我将快速介绍一下正则表达式:

^\D+ = 从字符串的开头,给我找一些不是数字的东西一次或多次。

\d+$ = 给我找一组紧跟在字符串末尾的一个或多个数字。

EDIT2:我想我没有回答你的第二个问题。根据表单如何从房间列表初始化、您如何存储复选框、您希望如何处理它、存在哪些其他数据结构来保存其余信息等等,答案可能会有很大差异上。

关于c# - 窗口形式 c# 对房间列表进行排序,这是一个字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8216610/

相关文章:

c# - 调试器可视化工具和 "Type is not marked as serializable"

visual-studio-2008 - 当我的单元测试在 Visual Studio 2008 中运行时,如何查看控制台输出?

visual-studio-2008 - 无法在 Silverlight 项目上使用 Visual Studios 进行调试

c# - 在 C# 代码中解析(大)XML 的最佳方法是什么?

c# - 实现代码问题

c# - 在 ViewportControl WP8 中移动对象

c# - WPF TreeViewItem 切换按钮可见性

c# - 开发环境DistributedCache.RoutingClient错误

c# - HttpClient PostAsJsonAsync 方法无法正常工作(序列化无法正常工作)

c# - 在 .Net 中查找并替换 JSON 响应中的字符串