简体   繁体   English

WPF - ListView 的 ItemsSource 中的绑定不能是列表

[英]WPF - Binding in ListView's ItemsSource cannot be a List

I have a WPF application that I try to code using MVVM.The goal is to make something like a notification center, that lists different types of data.我有一个 WPF 应用程序,我尝试使用 MVVM 进行编码。目标是制作类似通知中心的东西,列出不同类型的数据。

To do this, I want to fill a ListView on the main page with different ViewModels.为此,我想用不同的 ViewModel 填充主页上的 ListView。 One ViewModel for each type of data.每种类型的数据一个 ViewModel。

The problem is: When I put a (not a list) ViewModel in my ListView, it works fine.问题是:当我在 ListView 中放置一个(不是列表)ViewModel 时,它工作正常。 But if I put a list in my ListView, the program crashes on startup.但是如果我在 ListView 中放入一个列表,程序就会在启动时崩溃。 I need the ListView to take a list (ObservableCollection perhaps) of mixed ViewModels.我需要 ListView 来获取混合 ViewModel 的列表(可能是 ObservableCollection)。

I receive the error “Items collection must be empty before using ItemsSource.”我收到错误消息“在使用 ItemsSource 之前,Items 集合必须为空。” at a seemingly random location in my code.在我的代码中看似随机的位置。 Completely removing the code where the exception appears just causes it to show somewhere else.完全删除出现异常的代码只会使其显示在其他地方。

I have the following:我有以下几点:

C#: C#:

public class MainViewModel : ObservableObject
{
    private List<IPageViewModel> _items;

    public MainViewModel()
    {
        _items = new List<IPageViewModel>
        {
            new StatusViewModel(),
            new SettingsViewModel(),
            new OverviewViewModel()
        };
    }

    public List<IPageViewModel> Items => _items ?? (_items = newList<IPageViewModel>());
}

XAML: XAML:

<Window x:Class="InfoCenter.Views.Main.MainView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:test="clr-namespace:InfoCenter.Views.Test"
        xmlns:main="clr-namespace:InfoCenter.Views.Main"
        xmlns:views="clr-namespace:InfoCenter.Views"
        xmlns:settings="clr-namespace:InfoCenter.Views.Settings"
        xmlns:status="clr-namespace:InfoCenter.Views.Status"
        xmlns:overview="clr-namespace:InfoCenter.Views.Overview"
        mc:Ignorable="d"
        Title="MainView" Height="450" Width="500" 
        MaxWidth="1920"
        WindowStyle="None" Loaded="MainViewLoaded" 
        SizeChanged="MainViewSizeChanged"
        PreviewKeyDown="OnPreviewKeyDown"
        GotFocus="OnGotFocus"
        Closing="OnClosing"
        ResizeMode="NoResize"
        d:DataContext="{d:DesignInstance main:MainViewModel}">

    <Window.Resources>
        <DataTemplate DataType="{x:Type overview:OverviewViewModel}">
            <overview:OverviewView />
        </DataTemplate>
        <DataTemplate DataType="{x:Type status:StatusViewModel}">
            <status:StatusView />
        </DataTemplate>
        <DataTemplate DataType="{x:Type settings:SettingsViewModel}">
            <settings:SettingsView />
        </DataTemplate>
    </Window.Resources>


    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="24" />
            <RowDefinition Height="*" />
            <RowDefinition Height="30" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="24" />
        </Grid.ColumnDefinitions>

        <Button Command="{Binding ButtonClickCommand}" CommandParameter="Minimize" Grid.Row="0" Grid.Column="1">
            <Image Source="/Resources/arrow-down-1.png"></Image>
        </Button>

        <ListView ItemsSource="{Binding Items}" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" ScrollViewer.HorizontalScrollBarVisibility="Hidden" PreviewMouseWheel="OnPreviewMouseWheel" ScrollViewer.VerticalScrollBarVisibility="Hidden">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="30" />
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*" />
                </Grid.ColumnDefinitions>

                <Label Grid.Row="0" Grid.Column="0" Content="{Binding Path=Items.Header}" />
                <ContentControl Grid.Row="1" Grid.Column="0" Content="{Binding}" />
            </Grid>

        </ListView>

        <StatusBar FlowDirection="RightToLeft" Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2">
            <Image Width="24" Height="24" Source="{Binding ConnectionIcon}" />
        </StatusBar>

    </Grid>
</Window>

I really hope that you can help.我真的希望你能帮忙。 I have been trying to fix it the whole day!我一整天都在努力修复它!

You have put one thing in the ListView contents here: A Grid control.您在此处的ListView内容中放置了一件事Grid控件。 Don't do that.不要那样做。 There are two ways to populate a ListView in XAML: Bind ItemsSource or put items inside the content of the ListView element.有两种方法可以在 XAML 中填充 ListView:绑定ItemsSource将项目放入ListView元素的内容中。 You can't do both, and you did both, so it threw an exception.你不能两者都做,而且你两者都做了,所以它抛出了一个异常。

Here's the ItemsSource version.这是 ItemsSource 版本。

<ListView 
    ItemsSource="{Binding Items}" 
    Grid.Row="1" 
    Grid.Column="0" 
    Grid.ColumnSpan="2" 
    ScrollViewer.HorizontalScrollBarVisibility="Hidden" 
    PreviewMouseWheel="OnPreviewMouseWheel" 
    ScrollViewer.VerticalScrollBarVisibility="Hidden"
    />

I'm not certain what that Grid is for;我不确定那个Grid是做什么用的; you may have to find somewhere else to put it.您可能需要找到其他地方来放置它。

But my guess is that want it to be used to display the items.但我的猜测是希望它用于显示项目。 We can do that by making it into an ItemTemplate .我们可以通过将它变成一个ItemTemplate来做到这一点。 I'm a little confused by it, though: What is Items.Header ?不过,我有点困惑:什么是Items.Header Items is a List, which has no Header property. Items是一个 List,它没有Header属性。 Does IPageViewModel have a Header property? IPageViewModel是否有Header属性? For the moment I'll assume that's the case;目前我假设是这样; let me know if I'm mistaken.如果我弄错了,请告诉我。

<ListView 
    ItemsSource="{Binding Items}" 
    Grid.Row="1" 
    Grid.Column="0" 
    Grid.ColumnSpan="2" 
    ScrollViewer.HorizontalScrollBarVisibility="Hidden" 
    PreviewMouseWheel="OnPreviewMouseWheel" 
    ScrollViewer.VerticalScrollBarVisibility="Hidden"
    >
    <ListView.ItemTemplate>
        <DataTemplate>
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="30" />
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*" />
                </Grid.ColumnDefinitions>

                <Label 
                    Grid.Row="0" 
                    Grid.Column="0" 
                    Content="{Binding Header}" 
                    />
                <ContentControl 
                    Grid.Row="1" 
                    Grid.Column="0" 
                    Content="{Binding}" 
                    />
            </Grid>
        <DataTemplate>
    </ListView.ItemTemplate>
</ListView>

Based on the error I would recommend to change your XAML as was mentioned earlier in "Items collection must be empty before using ItemsSource."根据之前在“使用 ItemsSource之前, 项目集合必须为空”中提到的错误,我建议更改您的 XAML

Try this XAML:试试这个 XAML:

     <ListView ItemsSource="{Binding Items}" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" ScrollViewer.HorizontalScrollBarVisibility="Hidden" PreviewMouseWheel="OnPreviewMouseWheel" ScrollViewer.VerticalScrollBarVisibility="Hidden">
         <ListView.View>
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="30" />
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*" />
                </Grid.ColumnDefinitions>

                <Label Grid.Row="0" Grid.Column="0" Content="{Binding Path=Items.Header}" />
                <ContentControl Grid.Row="1" Grid.Column="0" Content="{Binding}" />
            </Grid>
       </ListView.View>
     </ListView>

Hope it will be helpful!希望它会有所帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM