我有这门课:
public class Team
{
public int Id { get; set; }
public string Name { get; set; }
public ObservableCollection<Competency> Competencies { get; set; } = new ObservableCollection<Competency>();
public ObservableCollection<Employee> Employees { get; set; } = new ObservableCollection<Employee>();
}
这段代码对我有用:
<Page>
<Page.Resources>
<model:Employee x:Key="employees" />
<HierarchicalDataTemplate DataType="{x:Type model:Team}" ItemsSource="{Binding Employees}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Row.Name}" FontWeight="Bold" Margin="3,0,0,0" />
</StackPanel>
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type model:Employee}">
<StackPanel Orientation="Vertical">
<Border Padding="2" HorizontalAlignment="Stretch" VerticalAlignment="Center" BorderBrush="#FFC3CEDC" BorderThickness="0,1,0,0">
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="130" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal" Grid.Column="0">
<TextBlock Text="{Binding Row.FirstName}" FontWeight="Bold" Margin="3,0,0,0" />
<TextBlock Text="{Binding Row.LastName}" Margin="3,0,0,0" />
</StackPanel>
</Grid>
</Border>
</StackPanel>
</DataTemplate>
</Page.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- TreeListControl for Teams -->
<dxg:TreeListControl x:Name="teamEmployeesTree" Grid.Column="0" ItemsSource="{Binding TeamsItems}">
<dxg:TreeListControl.View>
<dxg:TreeListView
TreeDerivationMode="HierarchicalDataTemplate"
AutoExpandAllNodes="True"
ShowCheckboxes="True"
AllowRecursiveNodeChecking="False"
NewItemRowPosition="Top"
AllowPerPixelScrolling="True"
TreeColumnFieldName="Name"
NavigationStyle="Cell"
AllowDragDrop="True"
ShowDragDropHint="False"
ShowNodeImages="True"
UseEvenRowBackground="True"
EnterMoveNextColumn="False"/>
</dxg:TreeListControl.View>
<dxg:TreeListColumn FieldName="Name" />
<dxg:TreeListColumn FieldName="Competencies"/>
</dxg:TreeListControl>
</Grid>
</Page>
现在我想要的是另一种类型的子节点,所以我需要某种类型的分组:
Team (root)
- "Employees" (fixed node text, and when I click on this to present all employees for that team)
--Emp1
--Emp2
- "Competencies" - (fixed node text, and when I click on this to present all employees for that team)
-- Competency1
-- Competency2
我还需要复选框“Is TeamLead”,但仅限员工。
这是否可能并且每个节点组内有不同的列?
您有三个常规选项:
#1 修改数据结构。 如果您有机会修改数据结构,您可以简单地添加另一个级别,例如作为一个组的
Details
属性。
Team.cs
public class Team
{
public int Id { get; set; }
public string Name { get; set; }
public ObservableCollection<ITeamDetail> Details { get; set; } = new ObservableCollection<ITeamDetail>();
}
ITeamDetail.cs
public class ITeamDetail
{
int TeamId { get; set; }
}
能力详细信息.cs
public class CompetencyDetails : ITeamDetail
{
public int TeamId { get; set; }
public ObservableCollection<Competency> Competencies { get; } = new ObservableCollection<Competency>();
}
EmployeeDetails.cs
public class EmployeeDetails : ITeamDetail
{
public int TeamId { get; set; }
public ObservableCollection<Employee> Employees { get; } = new ObservableCollection<Employee>();
}
这将为您提供以下树结构:
Team
|__Employees
| |__Employee1
|
|__Competencies
|__Competency1
#2 修改
DataTemplate
如果您无法修改数据结构并且您的树是简单的一级结构,那么您可以在您在团队根模板中定义的专用 Empoloyess
中显示 Competencies
和 ListBox
列表。我不建议这样做,因为这会引入导航问题,因为两个 ListBox
元素将被 TreeView
解释为单个节点。该解决方案会产生最糟糕的结果。
作为第三种解决方案,您可以使用基于“扩展器控件”的自定义控件:
Generic.xaml
<Style TargetType="TeamView">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TeamView">
<ListBox ItemsSource="{Binding Teams}>
<ListBox.ItemsTemplate>
<DataTemplate DataType="Team">
<Expander Header="{Binding Name}">
<StackPanel>
<Expander Header="Employees"
Margin="8,0,0,0"
Padding="4,0,0,0">
<ListBox ItemsSource="{Binding Employees}" />
</Expander>
<Expander Header="Competencies"
Margin="8,0,0,0"
Padding="4,0,0,0">
<ListBox ItemsSource="{Binding Competencies}" />
</Expander>
</StackPanel>
</Expander>
</DataTemplate>
</ListBox.ItemsTemplate>
</ListBox>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
TeamView.cs
高度专业化的控制。
您可以通过添加两个
DataTemplate
类型的依赖属性,然后将其绑定到两个内部 DataTemplate
的
ListBox.ItemsTemplate
属性,使此控件接受两个级别中每一个级别的
ListBox
,从而增强应用程序的可扩展性元素。这样,更改数据模型就不会破坏该控件的模板。为简单起见,我在本示例中避免了这种开销。
您还可以覆盖默认的
ListBoxItem
模板以删除突出显示行为(只需定义不带任何触发器的普通模板)。
class TeamView : Control
{
public IList<Team> Teams
{
get => (IList<Team>)GetValue(TeamsProperty);
set => SetValue(TeamsProperty, value);
}
public static readonly DependencyProperty TeamsProperty = DependencyProperty.Register(
nameof(Teams),
typeof(IList<Team>),
typeof(DelayButton),
new PropertyMetadata(default));
static TeamView()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(TeamView), new FrameworkPropertyMetadata(typeof(TeamView)));
}
}