-1

我有一个 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 无法填充它,因为它是只读的。

有没有办法让设计类型数据系统工作而不使我的视图模型的集合属性可写?

4

2 回答 2

1

有没有办法让设计类型数据系统工作而不使我的视图模型的集合属性可写?

是的,您可以创建另一个视图模型类,仅用于设计目的,具有ObservableCollection<T>属性,并将视图的设计时间设置为该DataContext实例的实例:

d:DataContext="{d:DesignInstance Type=local:DesignTimeViewModel, IsDesignTimeCreatable=True}
于 2019-03-19T14:32:44.223 回答
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 正在被该控件内的某个东西读取,它就会失败。

于 2019-03-20T09:27:00.293 回答