2

silverlight (4) TreeView 컨트롤에서 다음과 같은 계층 구조를 구현하는 가장 좋은 방법은 무엇입니까? (항목 및 그룹은 트리에 존재할 수있는 클래스입니다).silverlight에서 여러 객체 유형을 계층 적으로 템플릿 화하는 방법


Group 
| 
|-Item 
| 
|-Group 
| | 
| |-Item 
| | 
| |-Item 
| 
|-Item 

구조체는 물론 필요에 따라 임의로 더 복잡 할 수 있습니다.

HierarchicalDataTemplates가이 방법에 접근하는 것처럼 보입니다.하지만 템플릿을 적용하여 다른 클래스를 올바르게 해석하는 방법을 이해하는 데 어려움이 있습니다.

비슷한 질문이 HierarchicalDataTemplate의 TargetType 속성을 사용하는 WPF에 대해 질문되었지만 액세스 할 수있는 것으로 보이지 않아 Silverlight 버전에서 해당 속성을 사용할 수 있는지 여부가 확실하지 않습니다. 내 환경에서.

답변

2

Silverlight의 경우이를 위해 변환기를 만들어야 할 수 있습니다. 예를 들어, "대상 유형 데이터 템플리트 선택기"또는 유사합니다.

고급 기능을 사용할 수도 있지만 여기에는 하드 코딩 된 형식의 데이터 템플릿 인스턴스를 제공 할 수있는 Silverlight 단위 테스트 프레임 워크의 예제가 있습니다. 일반화 된 버전은 약 20 분 안에 작성 될 수 있습니다.

이 템플릿을 사용하려면 데이터 템플릿의 인스턴스를 제공하십시오. 그렇다면 계층 적으로 만들어야 할 수도 있습니다. 여기

<local:DataTemplateSelector 
    x:Key="DetailsViewDataTemplate" 
    DefaultDataTemplate="{StaticResource DefaultDataTemplate}" 
    TestMethodTemplate="{StaticResource TestMethodDataTemplate}" 
    TestClassTemplate="{StaticResource TestClassDataTemplate}"/> 

그리고

이 구현 :

/// <summary> 
/// A specialized data template selector. 
/// </summary> 
public sealed class DataTemplateSelector : IValueConverter 
{ 
    /// <summary> 
    /// Gets or sets the default data template. 
    /// </summary> 
    public DataTemplate DefaultDataTemplate { get; set; } 

    /// <summary> 
    /// Gets or sets the test method template. 
    /// </summary> 
    public DataTemplate TestMethodTemplate { get; set; } 

    /// <summary> 
    /// Gets or sets the test class template. 
    /// </summary> 
    public DataTemplate TestClassTemplate { get; set; } 

    /// <summary> 
    /// Initializes a new instance of the DataTemplateSelector type. 
    /// </summary> 
    public DataTemplateSelector() 
    { 
    } 

    /// <summary> 
    /// Convert a value to a data template. 
    /// </summary> 
    /// <param name="value">The value.</param> 
    /// <param name="targetType">The target parameter.</param> 
    /// <param name="parameter">ConverterParameter value.</param> 
    /// <param name="culture">The culture parameter.</param> 
    /// <returns>Returns the object.</returns> 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     if (value != null) 
     { 
      Type type = value.GetType(); 

      if (typeof(TestMethodData).TypeHandle == type.TypeHandle) 
      { 
       return TestMethodTemplate; 
      } 
      else if (typeof(TestClassData).TypeHandle == type.TypeHandle) 
      { 
       return TestClassTemplate; 
      } 
     } 

     return DefaultDataTemplate; 
    } 

    /// <summary> 
    /// No 2-way databinding support. 
    /// </summary> 
    /// <param name="value">The value.</param> 
    /// <param name="targetType">The target parameter.</param> 
    /// <param name="parameter">ConverterParameter value.</param> 
    /// <param name="culture">The culture parameter.</param> 
    /// <returns>Returns the object.</returns> 
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     return null; 
    } 
} 
+0

감사는이 후속하는 나를 너무 오래 걸렸다. 솔루션을 구현하려했지만 실패했습니다. 나는 템플릿 databind에서 변환기를 사용하기위한 구문을 이해할 수 없었다. ItemsTemplate = "{Binding Converter = {StaticResource ConverterInstance}}"와 비슷합니다.하지만 그렇게 할 수는 없습니다. 그러나 그것은 당신의 것이 좋은 접근이라고 내게 충격을줍니다. 내 데이터 객체에 대한 하위 컬렉션 및 참조를 포함하는 TreeNode 클래스를 만들었습니다. 단점은 트리의 각 항목을 유형에 따라 스타일을 지정할 수 없다는 것입니다. –

1

내 구현

<UserControl.Resources> 

    <DataTemplate x:Key="DefaultDataTemplate"> 
     <TextBlock Text="Default"/> 
    </DataTemplate> 

    <DataTemplate x:Key="ConditionDataTemplate"> 
     <Grid> 
      <TextBlock Text="{Binding ConditionType}" Margin="5" Width="100"/> 
     </Grid> 
    </DataTemplate> 

    <DataTemplate x:Key="ButtonDataTemplate"> 
     <Grid> 
      <Button Content="{Binding Name}"/> 
     </Grid> 
    </DataTemplate> 

    <DataTemplate x:Key="FieldDataTemplate"> 
     <Grid> 
      <Grid.ColumnDefinitions> 
       <ColumnDefinition/> 
       <ColumnDefinition/> 
       <ColumnDefinition/> 
      </Grid.ColumnDefinitions> 
      <ComboBox Grid.Column="0" ItemsSource="{Binding Fields}" SelectedItem="{Binding Name,Mode=TwoWay}" Margin="5,0,5,0"/> 
      <ComboBox Grid.Column="1" ItemsSource="{Binding ConditionTypes}" SelectedItem="{Binding ConditionType,Mode=TwoWay}" Margin="5,0,5,0"/> 
      <TextBox Grid.Column="2" Text="{Binding Value, Mode=TwoWay}" Margin="5" Width="100"/> 
     </Grid> 
    </DataTemplate> 

    <local:DataTemplateSelector 
      x:Key="DetailsViewDataTemplate" 
      DefaultDataTemplate="{StaticResource DefaultDataTemplate}" 
      ConditionDataTemplate="{StaticResource ConditionDataTemplate}" 
      FieldDataTemplate="{StaticResource FieldDataTemplate}" 
      ButtonDataTemplate="{StaticResource ButtonDataTemplate}"/> 
</UserControl.Resources> 
<Grid> 
    <sdk:TreeView ItemsSource="{Binding Tree}"> 
     <sdk:TreeView.ItemTemplate> 
      <sdk:HierarchicalDataTemplate ItemsSource="{Binding ChildNodes}"> 
        <ContentControl ContentTemplate="{Binding Converter={StaticResource DetailsViewDataTemplate}}" Content="{Binding}"/> 
      </sdk:HierarchicalDataTemplate> 
     </sdk:TreeView.ItemTemplate> 
    </sdk:TreeView> 
</Grid> 

MainClass

public class MainPageModel : BaseModel 
{ 
    private ObservableCollection<object> _Tree; 
    public ObservableCollection<object> Tree 
    { 
     get 
     { 
      return _Tree; 
     } 
     set 
     { 
      _Tree = value; 
      Notify("Tree"); 
     } 
    } 

    public MainPageModel() 
    { 
     Tree = new ObservableCollection<object>(); 
     Tree.Add(new Condition() 
     { 
      ConditionType = "OR", 
       ChildNodes = new ObservableCollection<object>() 
       { 
        new Field() 
         { 
          Name = "Поле 2", 
          ConditionType = "=", 
          Value = "3" 
        }, 
        new Field() 
         { 
          Name = "Поле 3", 
          ConditionType = ">", 
          Value = "3" 
        }, 
        new Field() 
         { 
          Name = "Поле 4", 
          ConditionType = "<", 
          Value = "3" 
        }, 
        new Condition() 
        { 
         ConditionType = "AND" , 
        ChildNodes = new ObservableCollection<object>() 
        { 
         new Field() 
          { 
           Name = "Поле 2", 
           ConditionType = "=", 
           Value = "3" 
          }, 
         new Field() 
          { 
           Name = "Поле 3", 
           ConditionType = ">", 
           Value = "3" 

         }, 
         new Field() 
          { 
           Name = "Поле 4", 
           ConditionType = "<", 
           Value = "3" 
         }, 
         new Button() 
         { 
           Name = "Добавить" 
         } 
        } 
       } 
      } 
      }); 
     Notify("Tree"); 
    } 
} 

public static class PickList 
{ 
    public static ObservableCollection<string> Fields 
    { 
     get 
     { 
      return new ObservableCollection<string>() { "Поле 1", "Поле 2", "Поле 3", "Поле 4" }; 
     } 
    } 

    public static ObservableCollection<string> ConditionType 
    { 
     get 
     { 
      return new ObservableCollection<string>() { ">", "<", "=" }; 
     } 
    } 
} 

public class Condition : BaseModel 
{ 
    private ObservableCollection<object> _ChildNodes; 
    public ObservableCollection<object> ChildNodes 
    { 
     get { return _ChildNodes; } 
     set { _ChildNodes = value; Notify("ChildNodes"); } 
    } 

    public string ConditionType { get; set; } 
} 

public class Field : BaseModel 
{ 
    public ObservableCollection<string> Fields 
    { 
     get 
     { 
      return PickList.Fields; 
     } 
    } 
    public ObservableCollection<string> ConditionTypes 
    { 
     get 
     { 
      return PickList.ConditionType; 
     } 
    } 

    public string Name { get; set; } 
    public string ConditionType { get; set; } 
    public string Value { get; set; } 
} 

public class Button : BaseModel 
{ 
    public string Name { get; set; } 
} 

변환기

,
public sealed class DataTemplateSelector : IValueConverter 
{ 

    public DataTemplate ConditionDataTemplate { get; set; } 

    public DataTemplate FieldDataTemplate { get; set; } 

    public DataTemplate ButtonDataTemplate { get; set; } 

    public DataTemplate DefaultDataTemplate { get; set; } 

    public DataTemplateSelector() 
    { 
    } 

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     if (value != null) 
     { 
      Type type = value.GetType(); 


      if (typeof(Condition).TypeHandle == type.TypeHandle) 
      { 
       return ConditionDataTemplate; 
      } 
      else if (typeof(Field).TypeHandle == type.TypeHandle) 
      { 
       return FieldDataTemplate; 
      } 
      else if (typeof(Button).TypeHandle == type.TypeHandle) 
      { 
       return ButtonDataTemplate; 
      } 
     } 

     return DefaultDataTemplate; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     return null; 
    } 
} 

내가 필드 디스플레이 유형 날짜 시간, 부울을 추가 할 계획 ... 귀하의 회신 및 사과에 대한

관련 문제