WPF设计时间数据中的ReadOnlyObservableCollection <t>

时间:2019-03-19 12:34:46

标签: c# wpf xaml design-data

我有一个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属性可写的情况下使设计类型数据系统正常工作?

2 个答案:

答案 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,则它将失败。