[英]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.