Моя реализация
<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;
}
}
Я планирую добавить типы отображения поля DateTime, Bool, ...