将ListView字段绑定到嵌套列表WPF

5

我有以下这些类:

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

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

如您所见,我有一个Sequence中的事件列表。我有一个Sequence列表。
我想展示一个ListView,其中包含Sequence列表的GridView。对于每个Sequence,我想要两列,一列是属性freq的值,另一列应该是与该Sequence相关联的事件列表。例如:enter image description here
其中第一行与第一个Sequence相关联。矩形的颜色代表事件类型。在第一个Sequence中,有以下事件:

  • 类型为“红色”的eserc 1
  • 类型为“红色”的eserc 2
  • 类型为“绿色”的eserc 3
  • 类型为“红色”的eserc 4

我知道我需要进行绑定以显示值,但我不知道如何为序列执行绑定,因为我应该将列的值绑定到每个单独Sequence内的Event对象的值。
这是我为ListView编写的代码:

<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”的东西,但我不确定,也不是很理解它的工作原理。我知道它可以在源是对象时起作用,但在这种情况下,它是一个对象列表,我不知道如何获取信息。

3
使用DataTemplate在第一列的单元格中显示您的嵌套列表(阅读有关GridViewColumn.CellTemplate的文档,并查看使用CellTemplate属性的示例,请参见此处:https://dev59.com/P2445IYBdhLWcg3wucmo)。 - user2819245
1
哦,关于着色,您可以使用DataTrigger实现,根据DataTrigger绑定的属性值更改颜色(http://www.wpf-tutorial.com/styles/trigger-datatrigger-event-trigger/)。 - user2819245
3
最后,要夸赞你提问的出色表现,包括一个涂鸦,使得理解你的目标变得非常容易。希望人们能更多地点赞那些形式良好的问题,而不仅仅是贬低写得差、缺乏努力的问题。 - user2819245
3
我记得我忘了补充一件事:“_我知道它在源是一个对象时能够工作,但在这种情况下它是一个对象的列表,我不知道如何获取信息_”。哦,你已经知道了。看吧,你已经知道如何展示一个List<Sequence>了:用ListBox/ListView。那么,你要如何在列单元格中展示你的List<Event>呢?没错,你猜对了;再次用ListBox/ListView... ;-) - user2819245
events可以包含多少个项目? - FoggyFinder
谢谢@elgonzo!我正在尝试实现您建议的内容,但遇到了许多问题.. 我认为我理解了主要思想,但是实现对我来说似乎很困难.. - A. Wolf
1个回答

3
为了实现这一点,您需要在第一个GridViewColumn内定义另一个列表,此列表应为水平的(编辑ItemsPanelTemplate)。您可以使用ListViewListBoxItemsControl(看起来最合适)。

要根据Event的类型绘制具有不同颜色的Border,您应该首先为ItemsControl项定义自定义DataTemplate,并使用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>

序列集合:

    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>'的类型比属性'Results.SequenceCollection'(其中Results是包含SequenceCollection的窗口类)不可访问”。 - A. Wolf
另外一件事,在OnPropertyChanged()方法中实现INotifyPropertyChanged接口,我需要做什么?(我在Results类中已经这样做了) - A. Wolf
1
关于第一个问题,只需确保该属性是公共的。对于通知更改,每当您希望在UI上反映出属性更改时,请在属性中调用onepropertychanged()。 - SamTh3D3v
1
非常感谢您的帮助!有了整个代码,我解决了问题!!感谢您的耐心 :) - A. Wolf
1
这是最有帮助的答案,具有完全运行的源代码。非常好。+1 - Hao Nguyen
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接