我有一个ViewModel,它的属性为ReadOnlyObservableCollection。定义如下:
public class MyViewModel
{
private ObservableCollection<string> myProtectedCollection;
public ReadOnlyObservableCollection<string> MyCollectionProperty { get; }
public MyViewModel()
{
this.myProtectedCollection = new ObservableCollection<string>();
this.MyCollectionProperty = new ReadOnlyObservableCollection<string>(this.myProtectedCollection);
this.myProtectedCollection.Add("String1");
this.myProtectedCollection.Add("String2");
this.myProtectedCollection.Add("String3");
}
}
然后,我创建了一个名为TestData.xaml的xaml文件,并将生成操作设置为DesignData。因为我有这个:
<local:MyViewModel
xmlns:local="clr-namespace:ScrapWpfApplication1"
xmlns:system="clr-namespace:System;assembly=mscorlib">
<local:MyViewModel.MyCollectionProperty>
<system:String>String 1</system:String>
<system:String>String 2</system:String>
</local:MyViewModel.MyCollectionProperty>
</local:MyViewModel>
最后我有一个MainWindow.xaml,其中包含以下内容:
<Window x:Class="ScrapWpfApplication1.MainWindow"
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:local="clr-namespace:ScrapWpfApplication1"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525"
d:DataContext="{d:DesignData Source=SampleData.xaml}">
<ListBox ItemsSource="{Binding MyCollectionProperty}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Window>
问题是这没有在Visual Studio设计器中显示我的示例数据。如果我将视图模型中的集合更改为ObservableCollection而不是ReadOnlyObservableCollection,则它将按预期工作。
我猜这是因为设计时数据系统正在创建一个虚拟的ReadOnlyCollection,但是XAML无法填充它,因为它是只读的。
是否可以在不使我的视图模型的collection属性可写的情况下使设计类型数据系统正常工作?
答案 0 :(得分:1)
是否可以在不使我的视图模型的collection属性可写的情况下使设计类型数据系统正常工作?
是的,您可以使用ObservableCollection<T>
属性创建另一个仅用于设计目的的视图模型类,并将视图的设计时间DataContext
设置为此视图的实例:
d:DataContext="{d:DesignInstance Type=local:DesignTimeViewModel, IsDesignTimeCreatable=True}
答案 1 :(得分:1)
我还没有一个完美的答案。但这是我终于完成的工作。
与其尝试使设计数据系统模拟只读集合,不如尝试。我已经为集合创建了一组新的示例数据,并让MainWindow.xaml代替了。
因此,我的TestData.xaml文件更改为此。实际上,它具有更多功能,但这只是该问题的一个示例,因此看起来相当空白。
<local:MyViewModel
xmlns:local="clr-namespace:ScrapWpfApplication1"
xmlns:system="clr-namespace:System;assembly=mscorlib">
</local:MyViewModel>
第二,我创建了另一个名为TestDataArray.xaml的测试数据文件,其中包含一个数组。确保将构建操作设置为DesignData。
<x:Array Type="system:String"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ScrapWpfApplication1"
xmlns:system="clr-namespace:System;assembly=mscorlib">
<system:String>String 1</system:String>
<system:String>String 2</system:String>
</x:Array>
最后,我将MainWindow.xaml文件更改为此。注意
上绑定的更改<Window x:Class="ScrapWpfApplication1.MainWindow"
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:local="clr-namespace:ScrapWpfApplication1"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525"
d:DataContext="{d:DesignData Source=SampleData.xaml}">
<ListBox ItemsSource="{Binding}" DataContext="{Binding MyCollectionProperty}" d:DataContext="{d:DesignData Source=SampleDataArray.xaml}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Window>
这适用于我的特定情况,但是如果将示例数据绑定到控件,并且该控件内部的内容正在读取ReadOnlyCollection,则它将失败。