У меня есть список, состоящий примерно из 100 объектов. Каждый объект имеет 2 свойства (имя, время удара). Класс выглядит следующим образом:
public class Trxs
{
public string punch_time { get; set; }
public string name { get; set;}
}
имя списка (Punch_Times):
List<Trxs> Punch_times = new List<Trxs>();
Это операции машины отпечатков пальцев. Я хочу заполнить представление списка на Мауи, чтобы данные были сгруппированы на основе имени, как показано ниже: Так и должно быть
Я попробовал следующую группировку списка, он показал список сгруппированным, но без имени группы. Имя списка (Trx_List):
var sorted = Punch_times.GroupBy(x => x.name)
.Select(grp => grp.ToList())
.ToList();
Trx_List.ItemsSource = sorted ;
результат выглядел так (имена групп пусты):
Я создал класс для представления нового списка, который будет источником элемента Trx_List следующим образом:
public class Grouped_list
{
public string emp_name { get; set; }
public List<Trxs> trxes { get; set; }
}
И создал новый список:
List<Grouped_list> new_list = new List<Grouped_list>();
но как скопировать элементы из (отсортировано) в (новый_список). Или это необходимо? как сделать источник элемента представления списка сгруппированным по имени?
Любая помощь, пожалуйста!
Спасибо
Я прочитал эту статью Microsoft (learn.microsoft.com/en-us/dotnet/maui/user-interface/controls/… ), но не смог отразить ее в соответствии со своими потребностями.
вы не создали класс для моделирования сгруппированных данных
Я создал класс для представления нового списка, который будет источником элементов Trx_List следующим образом: ` public class Grouped_list { public string emp_name { get; набор; } публичный список <Trxs> trxes { get; набор; } }`
код, который вы разместили выше, не показывает, что вы на самом деле используете этот класс
Да. Извини. Я забыл добавить это. Я только что сделал.
Является ли List<Grouped_list>
типом sorted
? Если нет, то вы говорите, что не знаете, как построить такой список? Вероятно, в Linq есть какой-то способ сделать это, но сейчас мне это не приходит в голову. Перебрать все предметы. Для каждого элемента проверьте, содержит ли new_list список Grouped_List с соответствующим именем. Если нет, создайте такую группу, добавьте ее в основной список. Затем добавьте элемент в группу (найденную или созданную).
@ToolmakerSteve Я действительно новичок в Мауи и C# в целом. но ответ Liqun решил эту проблему, которая кажется простой задачей для профессионалов, но для меня это сводило меня с ума ლಠ益ಠ)ლ.
public class Grouped_list : List<Trxs>
{
public string emp_name { get; set; }
public Grouped_list(string name, List<Trxs> list) : base(list)
{
emp_name = name;
}
}
Вам нужно что-то подобное.
И тогда ваша наблюдаемая:
public ObservableCollection<Grouped_list> GroupedLists...
Установите его как ItemSource и не забудьте установить для IsGrouped значение true.
В GroupHeaderTemplate должна быть привязка к emp_name. И его DataType должен быть Grouped_list.
Кроме того, это EmpName, а не emp_name. И GroupedList не Grouped_list. Соблюдайте соглашения об именах.
спасибо за ваше предложение. но я должен придерживаться списка, так как я к нему привык (◔ д◔). Но я попробую просмотр коллекции позже.
@AbedElHameedJaber изменения кода, которые я указал, применимы и для ListView. И это не предложение.
Честно говоря, я рекомендую использовать CollectionView вместо ListView. Существует известная проблема с iOS GroupHeaderTemplate:ListView GroupHeaderTemplate создает пустые заголовки на iOS и MacCatalyst . Он просто отображает пустые заголовки. Вот почему я рекомендую использовать CollectionView. Использование почти такое же. Вы можете обратиться к Отображать сгруппированные данные в CollectionView.
В вашем случае действительно важно, как отразить отсортированный в new_list. Я сделал небольшую демонстрацию по официальной документации на основе вашего кода.
Для MainPageViewModel.cs,
public class MainPageViewModel
{
public List<Trxs> Punch_times { get; set; } = new List<Trxs>();
public List<Grouped_list> new_list { get; set; } = new List<Grouped_list>();
public MainPageViewModel()
{
//Add some data for test
Punch_times.Add(new Trxs
{
name = "John",
punch_time = "13:33"
});
......
// translate list to dict (key is name)
var dict = Punch_times.GroupBy(o => o.name)
.ToDictionary(g => g.Key, g => g.ToList());
foreach (KeyValuePair<string, List<Trxs>> item in dict)
{
new_list.Add(new Grouped_list(item.Key,new List<Trxs>(item.Value)));
}
}
}
Для Grouped_list.cs,
public class Grouped_list : List<Trxs>
{
public string Name { get; set; }
public Grouped_list(string name, List<Trxs> trxs) : base(trxs)
{
Name = name;
}
}
Для MainPage.xaml, который использует ListView или CollectionView,
<CollectionView ItemsSource = "{Binding new_list}"
IsGrouped = "True">
<CollectionView.GroupHeaderTemplate>
<DataTemplate>
<StackLayout>
<Label Text = "{Binding Name}" TextColor = "Black" VerticalOptions = "CenterAndExpand"
BackgroundColor = "LightGray"
FontSize = "20"
FontAttributes = "Bold" />
</StackLayout>
</DataTemplate>
</CollectionView.GroupHeaderTemplate>
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout>
<Label Text = "{Binding punch_time}" BackgroundColor = "Yellow"
FontSize = "20" HorizontalTextAlignment = "Center"
VerticalOptions = "CenterAndExpand" HorizontalOptions = "CenterAndExpand"/>
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
или вы можете использовать ListView, но не правильно отображать на iOS, как я упоминал выше.
<ListView ItemsSource = "{Binding new_list}"
IsGroupingEnabled = "True">
<ListView.GroupHeaderTemplate>
<DataTemplate>
<ViewCell>
<Label Text = "{Binding Name}" TextColor = "Black" VerticalOptions = "CenterAndExpand"
BackgroundColor = "LightGray"
FontSize = "20"
FontAttributes = "Bold" />
</ViewCell>
</DataTemplate>
</ListView.GroupHeaderTemplate>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout>
<Label Text = "{Binding punch_time}" BackgroundColor = "Yellow"
FontSize = "20" HorizontalTextAlignment = "Center"
VerticalOptions = "CenterAndExpand" HorizontalOptions = "CenterAndExpand"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Для получения дополнительной информации вы можете обратиться к ListView: отображение сгруппированных данных и Отображение сгруппированных данных в CollectionView
Надеюсь, это сработает для вас.
Ликун, ты гений. Я пытался решить эту задачу более 2 дней, и ваш код решил мою проблему. ╰(▔∀▔)╯. Но почему Grouped_list
должен наследовать от List<Trxs>
? разве мы не можем просто создать новый список и напрямую скопировать в него значения?
Спасибо за ваш ответ @Abed ElHameed Jaber. Каждый элемент Grouped_list в new_list заполняет данные одной группы в ListView. Он должен быть перечислимым для Trxs, поскольку каждый элемент в DataTemplate будет перечислять Grouped_list, чтобы каждый экземпляр Trxs заполнял строку. Это точно так же, как ItemSource ListView должен быть установлен в IEnumerable<T>.
Извините, что здесь уже слишком поздно. Если есть вопросы, отвечу завтра. И я не гений. Вопрос почти занял у меня большую часть дня. Я думаю, что ключевым моментом проблемы является изменение sorted на new_list, который может использоваться listview.
Сделано с удовольствием
Я должен уточнить, что я не прошу принять. Выбор ответа полностью зависит от вас, и только вы знаете, какой ответ поможет вам больше всего. Я просто хочу, чтобы мой ответ помог большему количеству людей с подобным вопросом. Извините, если мои слова повлияли на ваше мнение ~ Хороших выходных.
Привет Ликун. Нет, твои слова не повлияли на мое суждение, братан. Ваше решение фактически решило мою проблему, и точка.
ХОРОШО. Вы читали документы по группировке
LIstView
? Это довольно просто сделать, и есть много существующих вопросов по этой теме. И, пожалуйста, найдите время, чтобы отформатировать код, чтобы он был читабельным.