Привязка поля ListView к вложенному списку WPF

Имею следующие классы:

class Event {
int eserc {get;set;}
int type {get;set;}
}

class Sequence {
List<Event> events;
int freq {get;set;}
}

Как видите, у меня есть список событий внутри Последовательности. У меня есть список Sequence.
Я хочу показать Посмотреть список с Вид сетки со списком последовательностей. Для каждой последовательности я хочу иметь 2 столбца, один со значением свойства частота, а другой должен иметь список событий, связанных с этой последовательностью. Например: Привязка поля ListView к вложенному списку WPF
где первая строка относится к первой последовательности. Цвет прямоугольника представляет тип события. В первой последовательности есть следующие события:

  • eserc 1 типа "красный"
  • eserc 2 типа "красный"
  • eserc 3 типа "зеленый"
  • eserc 4 типа "красный"

Я знаю, что мне нужно выполнить привязку для отображения значений, но я не знаю, как это сделать для последовательностей, потому что я должен привязать значение столбца к значениям объектов Мероприятие в каждом отдельном Последовательность.
код, который я написал для Посмотреть список:

<ListView Name = "resultsList" Grid.Row = "5" Grid.Column = "1"
                  Grid.ColumnSpan = "3">
    <ListView.View>
                <GridView>

            <GridViewColumn Header = "Sequence" Width = "450"
                                    DisplayMemberBinding = "{Binding events}"/>
            <GridViewColumn Header = "Frequence" 
                                    DisplayMemberBinding = "{Binding freq}"/>
        </GridView>
    </ListView.View>
</ListView>

Конечно, Обязательные события неверно, потому что это сработало бы, только если бы это была строка, но это идея.
Я искал в Интернете и думаю, что мне следует использовать что-то вроде DataTemplate, но я не уверен в этом, и я не очень хорошо понимал, как это работает. Я понял, что это работает, когда источником является объект, но в данном случае это Список объектов, и я не знаю, как получить информацию.

Используйте DataTemplate, чтобы отобразить вложенный список в ячейках первого столбца (прочтите документацию для GridViewColumn.CellTemplate, а для примера использования свойства CellTemplate см. Здесь: stackoverflow.com/questions/4725352/…)

user2819245 20.03.2018 19:11

О, и цвет, который вы можете реализовать с помощью DataTrigger, меняющего цвет в зависимости от значения свойства, к которому привязан DataTrigger (wpf-tutorial.com/styles/trigger-datatrigger-event-trigger)

user2819245 20.03.2018 19:19

Наконец, +1 за отличную формулировку вашего вопроса, включая каракули, чтобы вам было так легко понять, какова ваша цель. Желаю, чтобы люди чаще голосовали за правильно сформулированные вопросы, чем просто против плохо написанных простых вопросов.

user2819245 20.03.2018 19:30

Я только помню, что забыл добавить одну вещь: «Я понял, что это работает, когда источником является объект, но в данном случае это список объектов, и я не знаю, как получить информацию.». О, ты уже знаешь. Видите ли, вы уже знаете, как отображать List <Sequence>: с помощью ListBox / ListView. Итак, как бы вы отобразили свой List <Event> в ячейке столбца? Ага, как вы уже догадались; опять же, с ListBox / ListView ... ;-)

user2819245 20.03.2018 19:57

сколько предметов может содержать events?

FoggyFinder 20.03.2018 21:49

Спасибо, @elgonzo! Я пытаюсь реализовать то, что вы предлагаете, но со многими проблемами ... Думаю, я понял основную идею, но реализация кажется мне сложной ...

A. Wolf 21.03.2018 01:53
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
5
6
1 203
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Для этого вам нужно определить другой список внутри первого GridViewColumn, список должен быть горизонтальным (отредактируйте ItemsPanelTemplate). Вы можете выбрать ListView, ListBox или ItemsControl (кажется наиболее подходящим).

Чтобы нарисовать Border с разными цветами в зависимости от типа Event, вы должны сначала определить собственный DataTemplate для элементов ItemsControl и использовать DataTrigger для установки цвета, здесь полный xaml для этого:

<ListView Name = "ResultsList" 
             ItemsSource = "{Binding SequenceCollection}">
        <ListView.View>
            <GridView>
                <GridViewColumn Header = "Sequence" Width = "450" >
                    <GridViewColumn.CellTemplate>
                        <DataTemplate>
                            <ItemsControl ItemsSource = "{Binding Events}">
                                <ItemsControl.ItemsPanel>
                                   <ItemsPanelTemplate>
                                       <StackPanel Orientation = "Horizontal"></StackPanel>
                                   </ItemsPanelTemplate>
                               </ItemsControl.ItemsPanel>
                                <ItemsControl.ItemTemplate>
                                    <DataTemplate>
                                        <Border>
                                            <Border.Style>
                                                <Style TargetType = "Border">
                                                    <Style.Triggers>
                                                        <DataTrigger Binding = "{Binding Type}" Value = "red">
                                                            <Setter Property = "Background" Value = "red"/>
                                                        </DataTrigger>
                                                        <DataTrigger Binding = "{Binding Type}" Value = "green">
                                                            <Setter Property = "Background" Value = "Green"/>
                                                        </DataTrigger>
                                                    </Style.Triggers>
                                                </Style>
                                            </Border.Style>
                                            <TextBlock Text = "{Binding Eserc, StringFormat='{}{0} '}"></TextBlock>
                                        </Border>
                                    </DataTemplate>
                                </ItemsControl.ItemTemplate>
                            </ItemsControl>
                        </DataTemplate>
                    </GridViewColumn.CellTemplate>
                </GridViewColumn>
                <GridViewColumn Header = "Frequence" 
                                DisplayMemberBinding = "{Binding Freq}"/>
            </GridView>
        </ListView.View>
    </ListView>

Коллекция SequenceCollection:

    private ObservableCollection<Sequence> _sequenceCollection =new ObservableCollection<Sequence>()
    {
        new Sequence(){Events = new ObservableCollection<Event>()
        {
            new Event(){Eserc=1, Type = "red"},
            new Event(){Eserc=2, Type = "red"},
            new Event(){Eserc=3, Type = "green"},
            new Event(){Eserc=4, Type = "red"},
        },Freq = 3}
    };
    public ObservableCollection<Sequence> SequenceCollection
    {
        get { return _sequenceCollection; }
        set
        {
            if (Equals(value, _sequenceCollection)) return;
            _sequenceCollection = value;
            OnPropertyChanged();
        }
    }

И вот вам классы с необходимыми приращениями:

public class Event
{
    public int Eserc { get; set; }
    public string Type { get; set; }
}

public class Sequence
{
    public ObservableCollection<Event> Events { get; set; }
    public int Freq { get; set; }
}

Выход:

shot

На стороне:

  1. не забудьте определить общедоступные свойства, чтобы иметь возможность правильно их связывать
  2. используйте соглашение об именах
  3. используйте ObservableCollection вместо List (они реализуют ICollectionChanged, который удобен для уведомлений об изменениях)
  4. не забудьте реализовать интерфейс INotifyPropertyChanged

Ух ты! Спасибо за ваш ответ! Я попытался реализовать его, но у меня возникли некоторые проблемы .. Во-первых, это дает мне ошибку в определении свойства SequenceCollection, говоря, что "тип свойства ObservableCollection <Sequence> менее доступен, чем свойство" Результаты. SequenceCollection »(где Results - это класс окна, содержащего SequenceCollection).

A. Wolf 21.03.2018 01:46

Другое дело, реализация интерфейса INotifyPropertyChanged в методе OnPropertyChanged (), что мне нужно сделать? (Я сделал это в классе результатов)

A. Wolf 21.03.2018 01:51

Что касается первой проблемы, просто убедитесь, что собственность является общедоступной. А для изменения уведомления, когда вы хотите, чтобы изменения свойства отражались в пользовательском интерфейсе, вызовите onepropertychanged () в свойстве.

SamTh3D3v 21.03.2018 08:22

Спасибо @Usama, за свойство проблема заключалась в том, что классы Event и Sequence не были общедоступными. Вместо этого для INotifyPropertyChanged я могу понять, как это сделать, я думаю, поэтому результаты не появляются. Я последовал этому руководству wpf-tutorial.com/data-binding/responding-to-changes, реализовав этот интерфейс для классов Sequence и Event.

A. Wolf 21.03.2018 09:21

Хорошо :)), пожалуйста, примите ответ, если вы сочли его полезным.

SamTh3D3v 21.03.2018 09:31

Это было полезно, но я не смог запустить его :( Это было именно то, что я хотел, но последовательность не отображается! Можете ли вы опубликовать код .cs всего окна, содержащего свойство SequenceCollection? Потому что я наверняка Я делаю глупые ошибки. Спасибо !!

A. Wolf 21.03.2018 09:40

Сделаю, как только я выйду из поезда

SamTh3D3v 21.03.2018 09:45

Большое спасибо! Когда, конечно, успеешь :)

A. Wolf 21.03.2018 09:46

Спасибо большое за вашу помощь! Со всем кодом я решил проблему !! Спасибо за ваше терпение :)

A. Wolf 21.03.2018 11:09

Это наиболее полезный ответ с полностью работающим исходным кодом. Очень хорошо. +1

Hao Nguyen 21.08.2019 20:38

Другие вопросы по теме