2016-08-04 8 views
1

멀리 복잡한 실제 프로젝트에서 더 작은 테스트 프로젝트를 만들었지 만 생각은 같습니다. 둘 다 똑같은 문제가 있습니다.FrameworkElement가 ContentControl의 속성 일 때 스타일 지정/바인딩

두 개의 클래스 A와 B가 있습니다. A는 ContentControl 유형이고 B는 FrameworkElement 유형입니다. A는 Bee (B 유형)의 종속성 속성을가집니다. B에는 종속성 속성 Text (문자열 유형)가 있습니다. A의 기본값은 null이고 B의 기본값은 "B There!"입니다.

내 테스트 창 (Window.Resources)에서 스타일을 사용하여 B의 Text 속성을 기본값 이외의 값으로 설정합니다.

<Window.Resources> 
    <Style TargetType="local:B"> 
     <Setter Property="Text" Value="YO!!!"/> 
    </Style> 
</Window.Resources> 

A.Content를 B의 새 인스턴스로 설정하면 시스템이 모든 것을 처리하기 때문에 모든 것이 매력처럼 작동합니다. 나는. Visual Studio의 디자이너에서 스타일 설정 기의 값을 변경하면 해당 속성 값 (B.Text)이 변경됩니다. 데이터 바인딩은 정상적으로 작동합니다. 실제로 다음과 같습니다 무엇이 필요

<local:A.Content> 
    <local:B/> 
</local:A.Content> 

은 ... 나는 이것에 대한 A.Content을 사용할 수 없습니다 통제 할 수없는 이유

그래서 새로운 B 인스턴스를 생성하고 A.Bee 속성으로 설정합니다. 이 경우 암시 적 스타일 및 데이터 컨텍스트 상속이 작동하지 않습니다. 나는. 스타일 설정 기의 값을 변경하면 아무 일도 일어나지 않고 데이터 바인딩이 작동하지 않습니다. A.Bee 속성 값에

<local:A.Bee> 
    <local:B/> 
</local:A.Bee> 

내가 나무에 B의 인스턴스를 넣어 작업을 데이터 바인딩을 바인딩 AddLogicalChild, AddVisualChild 및 데이터를 사용하여 콜백을 변경했습니다. 나는. A.Bee가 설정되면 다음이 발생합니다 (단순화 됨) ...

private static void BeeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
{ 
    A instanceOfA = d as A; 
    B newValue = e.NewValue as B; 

    Binding b = new Binding("DataContext"); 
    b.Source = instanceOfA; 

    BindingOperations.SetBinding(newValue, B.DataContextProperty, b); 

    instanceOfA.AddLogicalChild(newValue); 
    instanceOfA.AddVisualChild(newValue); 
} 

데이터 바인딩 문제가 해결되었습니다. 이것이 올바른 방법인지 확실하지 않지만 작동합니다. 더 좋은 방법이 있는지 알려주세요. 그러나 Visual Studio의 디자이너에서는 여전히 스타일이 작동하지 않습니다.

어떻게 Visual Studio 디자이너에서 스타일 설정 기의 값을 변경할 때 속성 값이 변경되도록 스타일 값에 바인딩 할 수 있습니까? AddLogicalChild이

필요한 경우를 나는 확실히이 올바른 트랙에있어 아니라 생각 때문에 사용, 아직 ... 때까지

NEWVALUE 내가 내 프로젝트에 대한 링크를 추가 할 수 있습니다, 자원에는 스타일이 없습니다 누군가가 그것을 테스트/수정하려고한다면. 여기


테스트 솔루션에 대한 링크입니다 (비주얼 스튜디오 2013) : 간단히 말해서 FEStyleTesting


, 방금처럼 작동하는 B 클래스의 인스턴스로 A.Bee 속성을 설정하려는 A.Content 속성을 B 클래스의 인스턴스로 설정합니다. 나는. Visual Studio Designer를 사용할 때 데이터 컨텍스트와 스타일은 B 클래스의 인스턴스에 상속됩니다.이미지에서

Debugging designer


, 나는 디자이너를 디버깅하고있어 당신이 볼 수 있듯이, AddLogicalChild가 호출 된 후 스타일 호텔은 자원에서 찾을 수 있지만, 어떤 이유로 스타일이 적용되지 않습니다 디자이너에서 ... 그리고 InstantietedElementViewNode 속성에 대한 세 번째 setter가 디자이너에 있습니다. 나는. 실행 시간에는 존재하지 않습니다. 어쩌면 그것은 디자이너가 모든 컨트롤에 추가하는 것입니다. 처음 두 세터는 XAML에 정의 된 세터입니다 (그림을 확장하는 것을 잊어 버렸습니다).


테스트 응용 프로그램에서 테스트를 위해 메시지 상자를 사용하는 것이 좋습니다. 나는. 변경할 시각적 모양 (Content 속성을 사용할 때)이 필요하지 않습니다. XAML에서 스타일 설정 기 값이 변경되면 호출 된 콜백을 가져 오면됩니다.

  1. 엽니 솔루션 : 여기

    이 문제를 테스트하는 단계입니다.
  2. 원본 탭 페이지가 열려 있지 않은지 확인하십시오.
  3. 경우에 따라 솔루션을 다시 빌드하십시오.
  4. MainWindow.xaml을 엽니 다 (두 번 클릭하십시오).
  5. 메시지 상자가 나타나면 "확인"버튼을 클릭하십시오.
  6. "이 작동하지 않습니다"에서 첫 번째 할당의 주석 처리가 해제되고 다른 세 개의 주석이 제거되었는지 확인하십시오. (어떤 이유로이 목록에서 소스 코드를 가져올 수 없습니다 ...)
  7. 이제 Text 속성의 스타일 설정 기 값을 예 : "YO2 !!!".
  8. "TextChanged"메시지 상자는 값을 편집 한 후에 나타나야합니다 (그러나 그렇지 않습니다). A.Content 속성을 사용하는 경우 I 데이터 바인딩 확인 스타일 상속 할 수 있도록

B는 목적에 ContentControl을 (그리고 FrameworkElement에서)로부터 유도된다. ContentControl은 FrameworkElement에서 파생되므로 결과는 동일해야합니다. 내 큰 프로젝트에서 FrameworkElement가 사용됩니다. 디자이너를 디버깅하는 동안

Debugging style value change.


, 나는 "YO을!"로 변경 ~ "YO2 !!!" XAML에서 B.Color를 명시 적으로 변경했습니다. 그런 다음 ColorChanged 콜백에서 B 인스턴스의 리소스를 살펴보고 그에 따라 값이 변경되었음을 알았습니다. 따라서 스타일 값은 XAML에서 변경 될 때 업데이트되지만 어떤 이유로 든 속성 값이 변경되지 않습니다 (텍스트는 여전히 "YO !!!"입니다). 따라서 콜백이 호출되지 않습니다. 나는 가능한 솔루션을 발견 할 수 있습니다


나는이 발생할 수 있습니다 궁금

.... AddLogicalChild를 호출했지만 A.LogicalChildren에는 B 개체가 포함되어 있지 않은 것으로 나타났습니다. 그런 다음 재정의 할 수있는 메서드를 통해 무시할 수있는 LogicalChildren 속성을 실행했습니다.

여기 내 버전입니다 : 이것은 "궁극적 인"솔루션입니다하지만 지금은 내 재산이 콜백 내가 스타일 세터 값을 변경할 때마다 호출 변경 한 경우

protected override IEnumerator LogicalChildren 
{ 
    get 
    { 
     List<object> list = new List<object>(); 

     while (base.LogicalChildren.MoveNext() == true) 
     { 
      try 
      { 
       list.Add(base.LogicalChildren.Current); 
      } 
      catch 
      { 
       // If Current fails, break. 
       break; 
      } 
     } 

     list.Add(Bee); 

     return list.GetEnumerator(); 
    } 
} 

확실하지. 글쎄, 살고 배우고 ... 이걸 좀 더 잘 테스트 해.

+0

A .. A.Bee .. 문제에 대한 귀하의 시도 된 해결책을 설명하기도 전에 문제를 잃었습니다. 하나의 문장을 사용하여 글을 쓰려고 할 수 있습니까? * "Visual Studio 디자이너에서 스타일 설정 기의 값을 변경할 때 속성 값이 변경되도록하기 위해 스타일 값에 바인딩하는 방법"* - 스타일 값이란 무엇입니까? 디자인 타임에 일어날 일을 제어하고 싶습니까? 런타임에 작동합니까? [mcve] (http://stackoverflow.com/help/mcve)로 시작하십시오. 여기에 게시하여 합리적인 설명을 추가하십시오 (원하는 내용과 대신 일어나는 내용). – Sinatr

+0

스타일 값은 Window.Resources의 스타일 설정자로 설정된 값입니다. 당신이 이해하지 못한다면 불평하기 전에 예시 프로젝트를 요청하십시오, 감사합니다. – ppsmxion

+0

그리고 예, 런타임이 작동하므로 Visual Studio 디자이너에 대해 언급했습니다. – ppsmxion

답변

0

따라서 문제는 중첩 된 개체를 포함하도록 LogicalChildren 속성을 재정의하는 것입니다. 이렇게하면 BindingOperations를 DataContext에 바인딩 할 필요가 없습니다. AddLogicalChild가 여전히 필요합니다. AddVisualChild에 대해서는 확실하지 않지만 미안한 것보다 안전합니다 ...