2010-08-10 6 views
5

이미 몇 가지 관련 질문이 있지만 다음 문제에 대한 깨끗한 해결책을 찾을 수 없었습니다.Silverlight의 액세스 요소 DataTemplate

여러 번 사용되는 데이터 템플릿 (예 : TreeViewItem.HeaderTemplate)이있는 경우 일부 TreeViewItems에 대해서만 템플릿을 어떻게 변경할 수 있습니까?

예를 들어, 내 TVI HeaderTemplate에 텍스트 블록이 있고 문자열에 따라 글꼴 두께를 굵게 지정한다고 가정 해 보겠습니다.

((TextBlock)myTreeView.Items.ElementAt(0).FindName("myTextBlock")).FontWeight = FontWeights.Bold; 

사람이에 대한 해결책이 있습니까 :

나는 이런 일을하고 싶지? -> 감사합니다 에반

편집 :은 데이터 템플릿의 경우에도 그것의 이름을 기준으로 컨트롤을 얻을 수있는 일반적인 함수를 작성하는 방법이 있나요?

LayoutRoot.FindName("myTextBlock"); myTextBlock이 datatemplate에없는 경우 작동합니다. findElementInDataTemplate(string elementName, string parentName) 함수를 작성하려면 어떻게해야합니까?

Evan의 대답이 내가 원하는 것을 찾지 못하는 이유는 컨트롤을 개발하고 있기 때문입니다. 내 컨트롤을 사용하는 응용 프로그램 개발자가 컨트롤의 모든 요소를 ​​변경할 수 있기를 바랍니다. Evan의 솔루션을 사용하면 응용 프로그램 개발자가 컨트롤의 모든 템플릿에 액세스 할 수 있어야합니다. 가능하지만 이상적은 아닙니다. 감사!

+0

GRD = 루트 요소 (당신이 찾고있는 요소의 부모는) LayoutRoot.FindName'의 일종을 가지고

("myTextBlock")'조작, "myTextBlock"이라고 불리는 많은 컨트롤 중 어느 것이 조작을 되 돌리시겠습니까? – AnthonyWJones

+0

@AnthonyWJones parentName 매개 변수를 포함하도록 편집하는 것이 좋습니다. – NickHalden

+0

@AnthonyWJones : 일반적으로 이름이있는 두 개의 컨트롤을 사용할 수 없습니다. 템플릿에 두 개의 동일한 이름 컨트롤을 유지하면 틀린 것으로 간주됩니다. – Mahantesh

답변

0

어떤 실버 라이트 버전입니까? 그리고이 게시물은 "Aug 8 at 18:55"의 몇 년입니까? 거기 될 것 같지 않습니다 SL4의 현재 버전에서

..

2

데이터 바인딩을 사용하는 경우 바인딩 변환기를 사용해 보셨습니까? 이 경우 ... 같은

FontWeight={Binding Path=TextProperty, Converter={StaticResource BoldConverter}} 

뭔가를 할 것 그리고 컨버터는 ...의 라인을 따라의 요소를 통해

string myTestString = (string)value; 
if (myTestString.Contains("Bob")) 
    return FontWeights.Bold; 
return FontWeights.Normal; 
시도하는 것이 덜 고통스러운하게

루트가 될 것입니다 특정 것을 찾으십시오.

+0

내 질문에 대한 훌륭한 해결책. 이제 내가 실제로 의미하는 질문을하고, 편집을 확인합니다. – NickHalden

1

이러한 요구 사항에 대한 나의 첫 번째 반응은 다음과 같습니다. 정말로 그렇게하고 싶습니까? 나는 일반적으로 개발자들에게 사용중인 기존 제어 패턴을 살펴 보라고 촉구했다. 이 경우 템플릿 컨트롤처럼 보일 것입니다.

물론 이것은 유연성을 제공하지 않습니다. 사용자 정의 컨트롤의 "성배"는 컨트롤의 전체 템플릿을 복제하지 않고 컨트롤에 대한 사소한 세부 사항을 조정하려는 욕구입니다. 물론 이것이 선언적으로 가능하지는 않습니다. 구문과 구문 규칙을 두려워한다면 그것을 선언 할 수 없습니다.

항상 예외가 있다고 말한 적이 있습니다. 그래서 저는이 일을해서는 안된다는 느낌에도 불구하고 가능한 옵션을 제시 할 것입니다.

이 오래된 answerDescendents 확장 메서드를 제공하므로 개체 트리 전체에서 컨트롤을 열거 할 수 있습니다.

내가 이것을 달성 한
TextBlock tb = treeViewItem.Descendents() 
       .OfType<TextBlock>() 
       .Where(t => t.Name == "myTextBlock") 
       .FirstOrDefault(); 
+0

IEnumerable 종속성 개체에 TypeOf에 대한 정의가 없습니다. – NickHalden

+0

@JGord : 코드 파일 맨 위에'using System.Linq'을 포함 시켰는지 확인하십시오. – AnthonyWJones

+0

이미 거기에 다른 함정이 있습니까? – NickHalden

4

한 가지 방법은을 사용하여 클래스 수준의 컬렉션을 변수에 필요한 모든 항목을 저장하는 것입니다 : - 당신이 후 당신이 TextBlock를 찾을 수 있어야 할 TreeViewItem의 인스턴스을 감안할 때 Loaded 컨트롤의 이벤트입니다.이 DataTemplate을 예로 들어 보겠습니다.

<DataTemplate> 
    ... 
    <TextBlock Loaded="TemplateTextBlock_Loaded" /> 
</DataTemplate> 

는 그런 다음 나중에 사용하기 위해 수집의 어떤 종류를로드 할 Loaded 이벤트를 사용합니다.

private List<TextBlock> templateTextBlocks = new List<TextBlock>(); 

private void TemplateTextBlock_Loaded(object sender, RoutedEventArgs e) 
{ 
    TextBlock tb = sender as TextBlock; 
    if (!this.templateTextBlocks.Contains(tb)) this.templateTextBlocks.Add(tb); 
} 

물론 컨트롤을로드 및 언로드하려는 경우이 방법이 효과가 없을 수 있습니다.

+0

이것은 나를 작동합니다, AnthonyWJones 대답은 시각 트리가 이미 생성되었을 때 유용했지만 이것도 마찬가지로 작동합니다. – hungryMind

0

도 TextBlock의 등이

TextBlock의 txtBlk = grd.FindName ("txtBlkName")을 시도 할 수 있습니다; 그런 다음 "myTextBlock"여러 번이라는 컨트롤이 포함 된 DataTemplate을 사용하는 경우