是否可能,如果是这样,在silverlight(4)TreeView控件中实现以下层次结构的最佳方法是什么? (其中Item和Group是树中可以存在的类)。
Group
|
|-Item
|
|-Group
| |
| |-Item
| |
| |-Item
|
|-Item
如果需要,结构当然可以比这更复杂。
HierarchicalDataTemplates似乎是解决这个问题的方法,但我特别难以理解如何应用模板来正确解释不同的类。
类似的问题被要求WPF,其答案是在HierarchicalDataTemplate上使用了TargetType属性,但我不确定该属性是否在silverlight版本中可用,因为我似乎无法访问它我的环境。
答案 0 :(得分: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;
}
}
答案 1 :(得分: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;
}
}
我打算添加Field显示类型DateTime,Bool,...