如何使用 Windows 資源管理器顯示項目和詳細信息展開/折疊 (How to Display Items and Details with Windows Explorer Expand/Collapse)


問題描述

如何使用 Windows 資源管理器顯示項目和詳細信息展開/折疊 (How to Display Items and Details with Windows Explorer Expand/Collapse)

I have some items that I want to show to the user in a WPF window, but I want to hide the details of each item until the user selects/expands the item. I'd like to achieve Windows‑Explorer‑esque functionality, where the item Header is always displayed, and the item Details (as an ItemsControl) are displayed when the user clicks on the item's arrow.

Is there an obvious way to do this? Or am I going to have to whip out a custom control?


參考解法

方法 1:

This can be done with the standard WPF Treeview.  Josh Smith's article on Simplifying the WPF TreeView includes a sample showing how to provide lazy‑loading of the data for the subitems within each TreeViewItem.

The basic approach is to make a "dummy" child of each item in the ViewModel, and track the expanded state of each TreeViewItem.  As a TreeViewItem is expanded, the dummy child is removed and replaced with the real data.

方法 2:

If you are just looking to automatically expand/collapse items then you probably want a trigger. For example you can use an expander and automatically Expand it when the mouse is over it.

                                <ControlTemplate.Triggers>
                                    <Trigger Property="IsMouseOver" Value="True">
                                        <Setter Property="IsExpanded" Value="True"/>
                                    </Trigger>
                                </ControlTemplate.Triggers>

And of course this can be repeated for other triggers that you want to set it to be open

        <Expander Header="Hello" IsExpanded="False">
            <Border Background="Red" Height="32"/>
            <Expander.Style>
                <Style TargetType="Expander">
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="Expander">
                                <StackPanel>
                                    <ContentPresenter Content="{TemplateBinding Header}"/>
                                    <ContentPresenter x:Name="expander" Content="{TemplateBinding Content}" Visibility="Collapsed"/>
                                </StackPanel>
                                <ControlTemplate.Triggers>
                                    <Trigger Property="IsMouseOver" Value="True">
                                        <Setter TargetName="expander" Property="Visibility" Value="Visible"/>
                                    </Trigger>
                                </ControlTemplate.Triggers>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>                                
                </Style>
            </Expander.Style>
        </Expander>

If you don't need a full tree like UI then it would probably be sufficient to just have a list of these, but I'm pretty sure you can also use the same trick on a treeviewitem too.

方法 3:

I took the ListBox of Expanders path, and I am pretty pleased with the results.

Here's how my final code ended up:

Control Template for Expander Button

        <ControlTemplate x:Key="TreeViewToggleButton" TargetType="{x:Type ToggleButton}">
            <Border x:Name="ToggleButtonBorder"
                    Background="{TemplateBinding Background}"
                    BorderBrush="{TemplateBinding BorderBrush}"
                    BorderThickness="{TemplateBinding BorderThickness}"
                    Padding="{TemplateBinding Padding}">
                <Grid>
                    <Rectangle Fill="Transparent"/>

                    <Path x:Name="Arrow"
                          Height="10" Width="10"
                          Stroke="Black"
                          Data="m 2 1 v 8 l 4 ‑3.75 Z">
                    </Path>
                </Grid>
            </Border>

            <ControlTemplate.Triggers>
                <Trigger Property="IsChecked" Value="True">
                    <Setter TargetName="Arrow" Property="Data" Value="m 2 9 h 5 v ‑5 Z"/>
                    <Setter TargetName="Arrow" Property="Fill" Value="Black"/>
                </Trigger>

                <Trigger Property="IsMouseOver" Value="True">
                    <Setter TargetName="Arrow" Property="Stroke" Value="#00A7C2"/>
                </Trigger>

                <MultiTrigger>
                    <MultiTrigger.Conditions>
                        <Condition Property="IsMouseOver" Value="True"/>
                        <Condition Property="IsChecked" Value="True"/>
                    </MultiTrigger.Conditions>

                    <Setter TargetName="Arrow" Property="Fill" Value="#00A7C2"/>
                </MultiTrigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>

Control Template for Expander

        <ControlTemplate x:Key="TreeViewExpander" TargetType="{x:Type Expander}">
            <DockPanel>
                <Grid DockPanel.Dock="Top">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition Width="*"/>
                    </Grid.ColumnDefinitions>

                    <ToggleButton x:Name="ExpanderButton"
                                  Grid.Column="0"
                                  Template="{StaticResource TreeViewToggleButton}"
                                  IsChecked="{Binding IsExpanded, RelativeSource={RelativeSource TemplatedParent}}"
                                  OverridesDefaultStyle="True"
                                  Padding="2, 0" />
                    <Label Grid.Column="1" Content="{TemplateBinding Header}"
                           Padding="0, 1"/>
                </Grid>

                <ContentPresenter x:Name="ExpanderContent"
                                  Visibility="Collapsed"
                                  DockPanel.Dock="Bottom"/>
            </DockPanel>

            <ControlTemplate.Triggers>
                <Trigger Property="IsExpanded" Value="True">
                    <Setter TargetName="ExpanderContent" Property="Visibility" Value="Visible"/>
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>

Usage in Window

    <ListBox Grid.Row="1" DataContext="{Binding Inputs}" ItemsSource="{Binding}" ScrollViewer.CanContentScroll="False">
        <ListBox.ItemContainerStyle>
            <Style TargetType="ListBoxItem">
                <Setter Property="ContentTemplate">
                    <Setter.Value>
                        <DataTemplate>
                            <Expander Template="{StaticResource TreeViewExpander}"
                                      IsExpanded="{Binding IsExpanded}">
                                <Expander.Header>
                                    <TextBlock Text="{Binding Timestamp, StringFormat=Time: {0}}"/>
                                </Expander.Header>
                                <ItemsControl ItemsSource="{Binding Variables}" Margin="30 0 0 0"/>
                            </Expander>
                        </DataTemplate>
                    </Setter.Value>
                </Setter>

                <Setter Property="IsSelected" Value="{Binding IsSelected}"/>
            </Style>
        </ListBox.ItemContainerStyle>
    </ListBox>

(by JosephReed CopseyAlSkiJoseph)

參考文件

  1. How to Display Items and Details with Windows Explorer Expand/Collapse (CC BY‑SA 3.0/4.0)

#controls #.net-4.0 #wpf






相關問題

如何在不阻塞的情況下用大量信息填充列表視圖? (How to populate listview with a lot of information without blocking?)

查看項目是否在列錶框控件中的最有效方法 (Most efficient way to see if an item is or is not in a listbox control)

tcng - 匹配“if”語句中的端口範圍 (tcng - match port range in "if" statement)

將圖像加載到面板 (Load image to panel)

Cycle2 Plugin Ẩn / Hiện các nút jQuery (Cycle2 Plugin Hide/Show buttons jQuery)

如何使用 Windows 資源管理器顯示項目和詳細信息展開/折疊 (How to Display Items and Details with Windows Explorer Expand/Collapse)

ASP.NET 2.0 JQuery AJAX 登錄 (ASP.NET 2.0 JQuery AJAX Login)

單步執行控件看不到第二個下拉菜單 (Step through controls fail to see second dropdown)

用戶控件、服務器控件和自定義控件之間有什麼區別? (What are the differences between User Controls, Server Controls & Custom Controls?)

GroupBox 控件中的圓角 (Rounded corners in GroupBox control)

在 .NET 中編寫大型多步驟表單的最有效方法是什麼? (Most efficient way to code a large multi-step form in .NET?)

如何從 ASP .NET MVC 中的動態生成控件中獲取數據? (How can I get data from dynamic generated controls in ASP .NET MVC?)







留言討論