Best way to "group" items "practically"?

I am working on a WPF control based on custom elements. For a “normal” layout, think of a vertical StackPanel, so my xaml will look something like this:

<mycontrol>
 <item1 />
 <item2 />
 <item3 />
</mycontrol>

In this case, its simple containers of 3 items are created, and all this is good. The control will look like this:

[item1]
[item2]
[item3]

To use case No. 2, I need to support horizontal "grouping" ... Ideally, my xaml would look like this:

<mycontrol>
 <item1 />
 <stackpanel orientation=horizontal>
  <item2a />
  <item2b />
  <item2c />
 </stackpanel>
 <item3 />
</mycontrol>

and in this case I would do as:

[item1]
[item2a] [item2b] [item2c]
[item3]

So, I'm going to create 5 item containers. I have already developed a custom layouts panel, and this part works.

, , 3 , , . - , "" , .

- , WPF, ? "" ?

, , - - :

<item1 />
<item2a isGrouped=true />
<item2b isGrouped=true />
<item2c isGrouped=true />
<item3 />

, isGrouped = true, , , , isGrouped 3 enum enum, . , xaml.

?

+4
1

, HierarchicalDataTemplate TreeView, TreeViewItem. . , ( TreeView , , ). :

<TreeView
    ItemsSource="{Binding Items}">
    <TreeView.Resources>
        <Color x:Key="SelectedBackgroundColor">#FFC5CBF9</Color>
        <Color x:Key="SelectedUnfocusedColor">#FFDDDDDD</Color>
        <Style
            TargetType="{x:Type TreeViewItem}">
            <Setter
                Property="ItemsPanel">
                <Setter.Value>
                    <ItemsPanelTemplate>
                        <StackPanel Orientation="Horizontal" />
                    </ItemsPanelTemplate>
                </Setter.Value>
            </Setter>
            <Setter
                Property="IsExpanded"
                Value="True" />
            <Setter
                Property="Template">
                <Setter.Value>
                    <!-- This template came from the example template and has just a few modifications.
                            Example is at: https://msdn.microsoft.com/en-us/library/ms752048.aspx -->
                    <ControlTemplate
                        TargetType="{x:Type TreeViewItem}">
                        <Grid>
                            <!-- Changed the grid configuration -->
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="auto" />
                                <ColumnDefinition Width="*" />
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                            </Grid.RowDefinitions>
                            <!-- The entire VisualStateGroups section is a direct copy+paste from the example template -->
                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="SelectionStates">
                                    <VisualState x:Name="Selected">
                                    <Storyboard>
                                        <ColorAnimationUsingKeyFrames
                                            Storyboard.TargetName="Bd"
                                            Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
                                        <EasingColorKeyFrame
                                            KeyTime="0"
                                            Value="{StaticResource SelectedBackgroundColor}" />
                                        </ColorAnimationUsingKeyFrames>
                                    </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Unselected" />
                                    <VisualState x:Name="SelectedInactive">
                                    <Storyboard>
                                        <ColorAnimationUsingKeyFrames
                                            Storyboard.TargetName="Bd"
                                            Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
                                        <EasingColorKeyFrame
                                            KeyTime="0"
                                            Value="{StaticResource SelectedUnfocusedColor}" />
                                        </ColorAnimationUsingKeyFrames>
                                    </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                                <VisualStateGroup x:Name="ExpansionStates">
                                    <VisualState x:Name="Expanded">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames
                                            Storyboard.TargetProperty="(UIElement.Visibility)"
                                            Storyboard.TargetName="ItemsHost">
                                        <DiscreteObjectKeyFrame
                                            KeyTime="0"
                                            Value="{x:Static Visibility.Visible}" />
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Collapsed" />
                                </VisualStateGroup>
                            </VisualStateManager.VisualStateGroups>
                            <!-- Removed the ToggleButton -->
                            <!-- Tweaked the placement of items in the grid -->
                            <Border
                                x:Name="Bd"
                                Background="{TemplateBinding Background}"
                                BorderBrush="{TemplateBinding BorderBrush}"
                                BorderThickness="{TemplateBinding BorderThickness}"
                                Padding="{TemplateBinding Padding}">
                                <ContentPresenter
                                    x:Name="PART_Header"
                                    ContentSource="Header"
                                    HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"/>
                            </Border>
                            <ItemsPresenter
                                x:Name="ItemsHost"
                                Grid.Column="1" />
                        </Grid>
                        <ControlTemplate.Triggers>
                            <!-- Removed the IsExpanded trigger -->
                            <MultiTrigger>
                                <MultiTrigger.Conditions>
                                    <Condition Property="HasHeader" Value="false" />
                                    <Condition Property="Width" Value="Auto" />
                                </MultiTrigger.Conditions>
                                <Setter
                                    TargetName="PART_Header"
                                    Property="MinWidth"
                                    Value="75" />
                            </MultiTrigger>
                            <MultiTrigger>
                                <MultiTrigger.Conditions>
                                    <Condition Property="HasHeader" Value="false" />
                                    <Condition Property="Height" Value="Auto" />
                                </MultiTrigger.Conditions>
                                <Setter
                                    TargetName="PART_Header"
                                    Property="MinHeight"
                                    Value="19" />
                            </MultiTrigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </TreeView.Resources>
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate
            DataType="{x:Type local:MyItem}"
            ItemsSource="{Binding Children}">
            <TextBlock Text="{Binding Name}" />
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
</TreeView>

ItemsSource , , :

internal class MyItem
{
    public string Name { get; private set; }

    public List<MyItem> Children { get; private set; }

    public MyItem(string name = null)
    {
        Name = name;
        Children = new List<MyItem>();
    }
}

, , , , . HeirarchicalDataTemplate ( TreeViewItem ) , .

, , :

public IEnumerable<MyItem> Items { get; private set; }

...

var items = new MyItem[]
{
    new MyItem("[First]"),
    new MyItem(),
    new MyItem("[Third]")
};
items[1].Children.Add(new MyItem("[Second_0]"));
items[1].Children.Add(new MyItem("[Second_1]"));
items[1].Children.Add(new MyItem("[Second_2]"));
Items = items;

Screen shot

, . 10 .

+1

All Articles