在Expression Blend中重复使用设计数据?

5

我有以下示例数据,这些数据可以很好地处理...

<SampleData:DashboardViewModel xmlns:SampleData="clr-namespace:MyApp.ViewModels">
    <SampleData:DashboardViewModel.Employees>
        <SampleData:EmployeeViewModel FirstName="Aaron" "Adams" />
        <SampleData:EmployeeViewModel FirstName="Billy" "Bob" />
        <SampleData:EmployeeViewModel FirstName="Charlie" "Chaplin" />
    </SampleData:DashboardViewModel.Employees>
</SampleData:DashboardViewModel>

然而,我发现能够重复使用那个样本员工列表会非常有用,而不是每次都重新输入。我无法弄清楚如何重复使用该列表。基本上,我想要另一个包含员工列表的SampleData文件(SampleEmployees.xaml),然后能够将其包含在我的其他示例中...

<SampleData:DashboardViewModel xmlns:SampleData="clr-namespace:MyApp.ViewModels">
    <SampleData:DashboardViewModel.Employees ... /> <!-- What goes in there? -->
</SampleData:DashboardViewModel>

<SampleData:OtherViewModel xmlns:SampleData="clr-namespace:MyApp.ViewModels">
    <SampleData:OtherViewModel.Employees ... /> <!-- What goes in there? -->
</SampleData:OtherViewModel>

此外,如何在另一个XAML文件中单独创建列表??
视图模型:
public class DashboardViewModel : NotificationObject
{
    public class DashboardViewModel(IDataService dataService)
    {
        InternalEmployees = new ObservableCollection<EmployeeViewModel>(dataService.GetEmployees());
        Employees = new ReadOnlyObservableCollection<EmployeeViewModel>(InternalEmployees);
    }

    private ObservableCollection<EmployeeViewModel> InternalEmployees { get; set; }
    public ReadOnlyObservableCollection<EmployeeViewModel> Employees { get; private set; }
}

所以基本上我需要将这个转化为在Microsoft Connect中的建议? - myermian
加油!请注意,VS2011是开发预览版,Blend 5也处于类似阶段,因此如果它们尚不支持此功能,我不预见它们会实现这个功能... - Jake Berger
如果Employees属性有一个setter并且是IList类型,那么这很容易处理,但是对于其他情况就不是那么简单了... - H.B.
@m-y:这可能有些困难,因为它是通用的。它也有一个setter吗? - H.B.
好的,让我用我的视图模型更新一下我的问题... - myermian
显示剩余3条评论
1个回答

0
在某些情况下,这是容易的,需要满足以下条件:
  1. 集合属性的类型为IEnumerable或IList(不是实现它的类)
  2. 该属性具有setter。
例如:public IEnumerable Employees { get; set; } 首先,您将项目提取到资源字典中,例如:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:obj="clr-namespace:Test.Objects">
    <x:Array x:Key="SampleEmps" Type="obj:Employee">
        <obj:Employee Name="Skeet" Occupation="Programmer" />
        <obj:Employee Name="Skeet" Occupation="Programmer" />
        <obj:Employee Name="Dimitrov" Occupation="Programmer" />
    </x:Array>
</ResourceDictionary>

然后将其添加到包含ViewModel的控件的MergedDictionary中。例如:

<Window.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="Objects/SampleData.xaml" />
        </ResourceDictionary.MergedDictionaries>
        <!-- ... -->

然后,您可以使用StaticResource引用集合:

<obj:SomeOtherViewModel Employees="{StaticResource SampleEmps}"/>

现在,专用集合的问题在于您无法简单地在 XAML 中创建它们。而缺少 setter 的问题在于您无法使用 StaticResource 分配属性,因此我认为 setter 总是必要的。

如果您有一个专用集合,可以使用 MarkupExtension 创建实例。

[ContentProperty("Items")]
public class GenericCollectionFactoryExtension : MarkupExtension
{
    public Type Type { get; set; }
    public Type T { get; set; }
    public IEnumerable Items { get; set; }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        var genericType = Type.MakeGenericType(T);
        var list = Activator.CreateInstance(genericType) as IList;
        if (list == null) throw new Exception("Instance type does not implement IList");
        foreach (var item in Items)
        {
            list.Add(item);
        }
        return list;
    }
}

你可以直接在资源中创建例如ObservableCollection,或者在需要项目的位置通过该扩展程序传输数组:

xmlns:om="clr-namespace:System.Collections.ObjectModel;assembly=System"

<obj:SomeViewModel x:Key="SomeVM">
    <obj:SomeViewModel.Employees>
        <me:GenericCollectionFactory Type="{x:Type om:ObservableCollection`1}"
                                     T="{x:Type obj:Employee}">
            <StaticResource ResourceKey="SampleEmps" />
        </me:GenericCollectionFactory>
    </obj:SomeViewModel.Employees>
</obj:SomeViewModel>

om:ObservableCollection末尾的`1是必要的,因为该类型是泛型。


我得找机会试试这个...不过,它有点味道。我不喜欢把我的样本数据建立在窗口资源中的想法。 - myermian
@m-y:您可以扩展上面的标记扩展,或创建另一个标记扩展,它可以在其他代码中获取资源而不需要对资源字典进行硬引用。 - H.B.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接