我有一个WPF应用程序,我尝试使用MVVM进行编码。目标是制作类似于通知中心的内容,列出不同类型的数据。
为此,我想在主页面上使用不同的ViewModel填充ListView。每种类型的数据都有一个ViewModel。
问题是: 当我在ListView中放入一个(不是列表)ViewModel时,它工作正常。但是如果我在ListView中放置一个列表,程序会在启动时崩溃。我需要ListView来获取混合ViewModel的列表(可能是ObservableCollection)。
我在代码中看似随机的位置收到错误“Items collection必须为空,然后才使用ItemsSource。”。完全删除出现异常的代码只会使其显示在其他地方。
我有以下内容:
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:
<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>
我真的希望你能提供帮助。我一整天都试图解决它!
答案 0 :(得分:2)
您已将{em>一件事放在ListView
内容中:Grid
控件。不要那样做。有两种方法可以在XAML中填充ListView:绑定ItemsSource
或将项目放在ListView
元素的内容中。你不能同时做到这两件事,而且你做了两件事,所以它引发了一个例外。
这是ItemsSource版本。
<ListView
ItemsSource="{Binding Items}"
Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="2"
ScrollViewer.HorizontalScrollBarVisibility="Hidden"
PreviewMouseWheel="OnPreviewMouseWheel"
ScrollViewer.VerticalScrollBarVisibility="Hidden"
/>
我不确定Grid
是什么意思;你可能必须找到其他地方才能把它。
但我的猜测是希望它用于显示项目。我们可以通过将其变为ItemTemplate
来实现这一目标。不过我对它有点困惑:什么是Items.Header
? Items
是一个List,没有Header
属性。 IPageViewModel
是否有Header
属性?目前我会认为是这样的;如果我弄错了,请告诉我。
<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>
答案 1 :(得分:0)
根据错误,我建议更改您的XAML,如前面"Items collection must be empty before using ItemsSource."中所述
试试这个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>
希望它会有所帮助!