2012-06-13 3 views
0

사용자 지정 DependencyProperty가있는 사용자 지정 UserControl이 있습니다. 이것을 사용하는 방법에 대한 더 나은 그림을 그리기 위해 UserControl은 마법사와 같은 컨트롤의 왼쪽 탐색 표시기입니다. 왼쪽 탐색 컨트롤은 마법사의 단계를 나타내는 각 컨트롤 안에 있습니다. 왼쪽 탐색 컨트롤 내부에서 다음과 비슷한 코드를 사용하여 몇 가지 변환기를 사용하여 가시성을 전환하고 여러 자식 컨트롤의 시각적 속성을 설정합니다. 아이템을 선택했는지 여부에 상관없이 내 StackPanel의 각 행의 전체 구조가 다르기 때문에 간단한 스타일 선택기 또는 스타일 선택 변환기를 사용할 수 없습니다.자식 컨트롤에서 부모 UserControl의 DependencyProperty에 바인딩하는 청결한 방법

이 코드는 내 컨트롤 전체에서 반복되어 하나의 사용자 지정 속성에 바인딩됩니다. 다음을 더 짧은 형식으로 만들거나이를 구현하는 더 깨끗한 방법이 있습니까?

<Polygon 
    Visibility="{Binding 
    RelativeSource={RelativeSource Mode=FindAncestor, 
    AncestorType=UserControl}, 
    Path=Selected, 
    Converter={StaticResource myCustomConverter}, 
    ConverterParameter='Expected String'}"> 
... 

상위 뷰

는 자식 컨트롤 사용자 정의하는 하나의 속성을 제공 :

<!-- Left Column --> 
    <views:LeftNavControl Selected="Item to Select..." /> 

답변

1

당신이 할 수있는 일이 있지만 그것을 더 깔끔하게/더 짧은 방법으로 설명하지는 않을 것입니다. 그들은 MVVM 접근법을 사용하는 경우 쉽게 구현할 수 있습니다.

가장 먼저 할 일은 바인딩에서 RelativeSource/AncestorType을 제거하여 바인딩 된 속성의 위치를 ​​찾는 것입니다. 두 컨트롤/모든 컨트롤 (사용하는 컨트롤의 개수가 명확하지 않은 경우)이 동일한 viewmodel을 공유하는 경우 동일한 viewmodel 속성을 views:LeftNavControl.Selected에 바인딩 할 수 있으며 모든 토글 된 표시 유형 컨트롤에 연결할 수 있습니다.

두 번째로 할 수있는 것은 xaml을 제거하는보다 급진적 인 방법이며 myCustomConverter도 쓸모 없게 만들지 만 뷰 모델에서 일부 비즈니스 로직을 옮길 것입니다. 이것은 Polygons/다른 컨트롤의 가시성 전환이 필요한 경우에 가장 적합합니다. 당신은 당신의 ViewModel에 StepXVisiblity 속성을 가질 수있다, 당신은 모양을 그 때마다 views:LeftNavControl.Selected 변경하고 다각형 (들) XAML을 계산할 수 :

<Polygon Visibility="{Binding StepXVisiblity}"> 

위의 설명의 간단한 예는 다음과 같습니다

<StackPanel> 
    <TextBox Text="{Binding Step, UpdateSourceTrigger=PropertyChanged}" /> 
    <TextBlock Text="One" Visibility="{Binding StepOneVisible}" /> 
    <TextBlock Text="One" Visibility="{Binding StepOneVisible}" /> 
    <TextBlock Text="Two" Visibility="{Binding StepTwoVisible}" /> 
    <TextBlock Text="Two" Visibility="{Binding StepTwoVisible}" /> 
</StackPanel> 

뷰 모델 :

public class MyVM : DomainBase 
{ 
    private int step; 

    public int Step 
    { 
     get 
     { 
      return step; 
     } 
     set 
     { 
      step = value; 
      OnPropertyChanged("Step"); 
      OnPropertyChanged("StepOneVisible"); 
      OnPropertyChanged("StepTwoVisible"); 
     } 
    } 

    public Visibility StepOneVisible 
    { 
     get 
     { 
      return step == 1 ? Visibility.Visible : Visibility.Collapsed; 
     } 
    } 

    public Visibility StepTwoVisible 
    { 
     get 
     { 
      return step == 2 ? Visibility.Visible : Visibility.Collapsed; 
     } 
    } 
} 
+0

<UserControl Name="thisControl" xmlns:local="yourLibrary"> <Polygon local:MagicHelper.Super="{Binding ElementName=thisControl, Path=Selected"/> ... 

미터 같은 것을 간다 (: 나는 그것을 테스트하지 않았기 때문에 의사 코드로 다음 사항을 고려 아니 프레임 워크, 방금 일부 VM을 기본 클래스와 헬퍼를 썼습니다),하지만 난 컨트롤에 아무것도 다른 사람을 위해 필요하지 않았기 때문에 나는 아직 VM에 의해이 컨트롤을지지하지 않았습니다. 이것은 분명히 논리적 인 방법입니다. 감사 – Rich

0

마음에 오는 유일한 것은 기본 중 하나에서 파생 자신의 바인딩 클래스를 생성하는 것입니다 (이 자체 마크 업 확장입니다.) 일반적으로 사용하는 기본값으로 모든 속성을 설정합니다. 그렇게하면 기본값이 아닌 것을 지정하면됩니다.

0

첫째, 당신이 말한 이후 탐색 패널의 라인을 따라 뭔가, listview 나 listbox와 같은 것을 사용하고 뷰 모델의 콜렉션에 바인드되는 동안 아이템을 템플릿 화하는 것에 대해 생각할 수 있습니다. 그러나 Nav 컨트롤의 범위를 알지 못하므로 Nav 컨트롤이이 구성표와 정확히 일치하지 않는다고 가정합니다.

첨부 된 속성을 사용하여 단일 부모 속성을 기반으로 여러 속성을 설정하는 방법을 설명 할 것을 제안합니다.

public class MagicHelper 
    { 
     #region Super Property 


     public static readonly DependencyProperty SuperProperty = 
      DependencyProperty.RegisterAttached(
       "Super", typeof(SecretType), typeof(MagicHelper) 
       new PropertyMetadata(-1, SuperChanged)); 

     // Get 
     public static SecretType GetSuper(DependencyObject obj) 
     { 
      return (SecretType)obj.GetValue(SuperProperty); 
     } 

     // Set 
     public static void SetSuper(DependencyObject obj, SecretType value) 
     { 
      obj.SetValue(SuperProperty, value); 
     } 

     // Change Event - make stuff happen here 
     public static void SuperChanged(
      DependencyObject obj, DependencyPropertyChangedEventArgs e) 
     { 

// I am using Polygon here for example but you could use a base class that might cover all your controls 
      if (!(obj is Polygon)) 
       return; 


      Polygon pGon = (Polygon)obj; 

     // do your thing to pGon here with e.NewValue 
     var mySecretInstance = e.NewValue as SecretType; 

     if (mySecretInstance.frap) 
     { 
     pGon.Visibility = Visibility.Collapsed; 
     pGon.Background = Brushes.Red; 
      } 

... 
... 

     } 

} 

와 XAML 내가 아주 가벼운 MVVM 구현을 사용하고

관련 문제