2011-11-22 67 views
5

我有以下的样本数据,其工作地非常好......在Expression Blend中重用设计数据?

<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; } 
} 
+0

我不认为这是可能的默认系统。我认为必须创建一个[CustomTool](http://www.google.com/search?q=visual+studio+custom+tool)来解析源文件,然后生成另一个设计数据文件。这将防止重新输入,但生成的生成文件仍然包含完整的数据(不是对其他数据的“引用”)。 –

+0

所以基本上我需要把它变成微软连接的建议? –

+0

去吧。注意VS2011在dev预览中,而Blend 5处于类似的阶段,所以如果他们不支持它,我不会预见他们实现这个功能... –

回答

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> 

然后,您将其添加到将包含ViewModels的控件的MergedDictionary。例如

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

然后你就可以参考使用StaticResource集合:

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

现在有了专门收藏的问题是,你不能简单地用XAML创建它们。而缺少二传手的问题是你不能使用StaticResource来分配财产,所以我认为一个二传手总是必要的。

如果您有专门的集合,则可以使用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> 

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

+0

当我有机会的时候,我将不得不尝试这个...虽然它确实有点味道。我不喜欢将我的示例数据构建到窗口资源中的想法。 –

+0

@ m-y:您可以扩展上面的标记扩展,或者创建另一个在其他代码中没有对其他代码中的资源字典的硬引用的情况下即时获取资源。 –