2011-11-22 2 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> 

그러나, 나는 그것을 매번 다시 입력하는 대신 샘플 직원의 목록을 재사용 할 수있는 것이 유용 할 것이라는 점을 찾을 수있다. 나는 그 목록을 재사용하는 방법을 알아낼 수 없다. 기본적으로,이 방법에서 별도로 목록을 작성하는 직원의 목록, 다음 내 다른 샘플이 포함 할 수 포함 된 다른 샘플 데이터 파일 (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

기본적으로 이것을 Microsoft Connect의 제안으로 바꾸어야합니까? –

+0

가십시오.VS2011은 개발자 프리뷰에 있으며 블렌드 5는 비슷한 단계에 있기 때문에 아직 지원하지 않는다면이 기능을 구현하지는 못할 것이라고 생각합니다. –

답변

0

는, 사람들은 필요합니다

  1. 컬렉션 속성 유형을 IEnumerable 또는 IList의 (안 클래스가 구현)
  2. 속성 세터가있다.

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에 그것을 추가 할 수 있습니다. 예 : 이제 전문 컬렉션의 문제는 단순히 XAML에서 그들을 만들 수 있다는 것입니다

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

:

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

그런 다음 당신은 다음 StaticResource를 사용하여 컬렉션을 참조 할 수 있습니다. 그리고 누락 된 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> 

`1을 유형이 일반이기 때문에 om:ObservableCollection 끝에 필요합니다.

+0

기회가 생겼을 때 이것을 시도해야합니다 ...하지만 냄새가납니다. 내 샘플 데이터를 창 리소스에 내장 할 필요가 없다는 생각이 듭니다. –

+0

@ m-y : 위의 마크 업 확장을 확장하거나 다른 코드의 리소스 사전에 대한 하드 참조없이 즉석에서 리소스를 가져 오는 마크 업 확장을 만들 수 있습니다. –