2013-04-22 2 views
2

현재 WPF의 유연성을 테스트하는 애플리케이션을 작성 중입니다. 그것의 ViewModel에 관해서는 꽤 투명한 것으로 의도 된 몇 가지 usercontrols 있습니다. 내가 투명하게 의미하는 것은 ViewController가 해당 usercontrol 내의 컨트롤에 바인드 될 모든 필수 속성을 가지고 있다면 사용자 정의 컨트롤이 모든 유형의 ViewModel을 사용할 수 있다는 것입니다. 나는 특정 UserControl에 대한 ViewModel을 datacontext로 할당하여이 작업을 수행합니다.몇 줄의 사용자 정의 컨트롤에 관계없이 사용자 정의 컨트롤 내에서 사용자 정의 컨트롤의 datacontext를 설정하십시오.

두 개의 usercontrol이있는 경우 (하나는 ViewModelLocator에 액세스하고 하나는 datacontext 선언을 필요로하는 경우)에 작동합니다. 3 단계 이상의 사용자 정의 컨트롤에 도달 할 때 무엇을해야할지 모르겠습니다. ViewModelLocator에 대한 액세스 권한이있는 usercontrol에있는 usercontrol 내에서 usercontrol의 datacontext를 설정하는 방법이 있습니까?

다음은 내 질문에 대한 명확한 설명입니다.

이 코드는 상위 usercontrol입니다. MAF를 사용하는 응용 프로그램에서 사용하기위한 것입니다. 비 정적 ViewModelLocator를 사용하여 각 플러그인 인스턴스가 ViewModelLocator의 다른 인스턴스를 사용하고 플러그인에 자체 app.xaml이 없으므로 (글로벌 리소스가 없음)이를 확인했습니다. 보시다시피, 나는 그리드에 별도의 어셈블리에서 usercontrol을 배치 한 다음 해당 usercontrol이 부모 usercontrol의 ViewModelLocator와 상호 작용할 수 있도록 datacontext를 선언했습니다.

<UserControl x:Class="TestApp.Inventory.Common.Views.MaterialsNewView" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:vm="clr-namespace:TestApp.Inventory.Common.ViewModel" 
      xmlns:views="clr-namespace:TestApp.Inventory.Common.Views" 
      xmlns:viewsSupp="clr-namespace:TestApp.Supplier.Common.Views;assembly=TestApp.Supplier.Common" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      mc:Ignorable="d" Height="607" Width="616" Loaded="UserControl_Loaded"> 

    <UserControl.Resources> 
     <vm:ViewModelLocator x:Key="Locator" /> 
    </UserControl.Resources> 

    <UserControl.DataContext> 
     <Binding Path="MaterialsNewView" Source="{StaticResource Locator}" /> 
    </UserControl.DataContext> 

    <Grid> 
     <views:SupplierView x:Name="supplierView" Margin="145,306,0,0" HorizontalAlignment="Left" Width="328" Height="258" VerticalAlignment="Top" DataContext="{Binding Source={StaticResource Locator}, Path=SupplierView}" /> 
    </Grid> 
</UserControl> 

그런 다음 하위 usercontrol에 대한 코드가 있습니다. 앞에서 말했던 것처럼, 하위 usercontrol은 ViewModel의 관점에서 투명 해졌습니다. 그래서 datacontext는 항상 부모 usercontrol에서 선언되어야합니다.

<UserControl x:Class="TestApp.Supplier.Common.Views.SupplierView" 
     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:ignore="http://www.ignore.com" 
     mc:Ignorable="d ignore" Height="289" Width="352" 
     xmlns:my="clr-namespace:TestApp.Lookup.Common.Views;assembly=TestApp.Lookup.Common"> 

    <Grid> 
     <my:MaterialTypeListView Height="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Grid, AncestorLevel=1}, Path=ActualHeight}" HorizontalAlignment="Left" Name="materialTypeListView1" VerticalAlignment="Top" Width="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Grid, AncestorLevel=1}, Path=ActualWidth}" /> 
    </Grid> 
</UserControl> 

내 문제는 하위 usercontrol에 자체 하위 usercontrol이있는 경우입니다. 부모 usercontrol에서 datacontext를 선언하는 방법을 모르겠습니다. 목적은 얼마나 많은 계층의 사용자 정의 컨트롤이 있더라도 상위 사용자 컨트롤의 ViewModelLocator와 상호 작용해야합니다.

답변

2

DependencyProperty을 MaterialTypeList라는 UserControl SupplierView에 추가하십시오. SupplierView에 UserControl을 MaterialNewView에 바인딩

public partial class SupplierView 
{ 
    public List<string> MaterialTypeList 
    { 
     get { return (List<string>)GetValue(MaterialTypeListProperty); } 
     set { SetValue(MaterialTypeListProperty, value);} 
    } 

    public static readonly DependencyProperty MaterialTypeListProperty = 
      DependencyProperty.Register("MaterialTypeList", typeof(string), typeof(SupplierView), 
      new PropertyMetadata(null)); 
} 

추가

<UserControl x:Class="TestApp.Supplier.Common.Views.SupplierView" 
      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:ignore="http://www.ignore.com" 
      mc:Ignorable="d ignore" Height="289" Width="352" 
      xmlns:my="clr-namespace:TestApp.Lookup.Common.Views;assembly=TestApp.Lookup.Common"> 

     <Grid> 
      <my:MaterialTypeListView 
DataContext="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl, AncestorLevel=1}, Path=MaterialTypeList}" 
Height="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Grid, AncestorLevel=1}, Path=ActualHeight}" HorizontalAlignment="Left" Name="materialTypeListView1" VerticalAlignment="Top" Width="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Grid, AncestorLevel=1}, Path=ActualWidth}" /> 
     </Grid> 
    </UserControl> 

이 MaterialTypeList에 MaterialTypeListView에 UserControl을 SupplierView에 바인딩 추가 MaterialTypeList합니다.

<UserControl x:Class="TestApp.Inventory.Common.Views.MaterialsNewView" 
       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
       xmlns:vm="clr-namespace:TestApp.Inventory.Common.ViewModel" 
       xmlns:views="clr-namespace:TestApp.Inventory.Common.Views" 
       xmlns:viewsSupp="clr-namespace:TestApp.Supplier.Common.Views;assembly=TestApp.Supplier.Common" 
       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
       xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
       xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
       mc:Ignorable="d" Height="607" Width="616" Loaded="UserControl_Loaded"> 

     <UserControl.Resources> 
      <vm:ViewModelLocator x:Key="Locator" /> 
     </UserControl.Resources> 

     <UserControl.DataContext> 
      <Binding Path="MaterialsNewView" Source="{StaticResource Locator}" /> 
     </UserControl.DataContext> 

     <Grid> 
      <views:SupplierView x:Name="supplierView" Margin="145,306,0,0" 
MaterialTypeList="{Binding [HERE YOUR LIST OF MATERIALTYPE]}" 
HorizontalAlignment="Left" Width="328" Height="258" VerticalAlignment="Top" DataContext="{Binding Source={StaticResource Locator}, Path=SupplierView}" /> 
     </Grid> 
    </UserControl> 
+0

빠른 응답을 보내 주셔서 감사합니다. 그러나 두 개의 usercontrols 다른 ViewModels 사용합니다. MaterialTypeListView가 ResourcesNewView에 의해 액세스되는 ViewModelLocator와 통신하여 ViewModel이 적절하고 어떤 경우 가능하면 MaterialsNewView에서 해당 바인딩을 선언 할 수있는 방법이 필요합니다. –

+0

내 대답이 변경되었습니다. 즉, materialtypelist를 바인딩 할 uc : SupplierView에 DependencyProperty를 추가합니다. –

+0

미안하지만 WPF에 익숙하지 않아서 DependencyProperty가 내 관심사를 어떻게 해결할 지 잘 모르겠다. 가능하면 좀더 정교하고 샘플 코드를 제공 할 수 있습니까? 고맙습니다. –

관련 문제