最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

WPF實(shí)現(xiàn)樹形表格控件的示例代碼

 更新時(shí)間:2024年04月02日 11:05:56   作者:趨時(shí)軟件  
這篇文章主要介紹了如何利用WPF框架實(shí)現(xiàn)樹形表格控件,該控件不僅能夠有效地展示復(fù)雜的層級(jí)數(shù)據(jù),還能夠提供豐富的個(gè)性化定制選項(xiàng),感興趣的可以了解下

前言

本文將探討如何利用WPF框架實(shí)現(xiàn)樹形表格控件,該控件不僅能夠有效地展示復(fù)雜的層級(jí)數(shù)據(jù),還能夠提供豐富的個(gè)性化定制選項(xiàng)。我們將介紹如何使用WPF提供的控件、模板、布局、數(shù)據(jù)綁定等技術(shù)來構(gòu)建這樣一個(gè)樹形表格。

一、運(yùn)行效果

1.1默認(rèn)樣式

1.2 自定義樣式

二、代碼實(shí)現(xiàn)

2.1 創(chuàng)建自定義控件(TreeListView)

新建一個(gè)繼承自TreeView的控件,并定義一個(gè)類型為ViewBase的View依賴屬性,用于在代碼中指定列。

public class TreeListView : TreeView
{
        public ViewBase View
        {
            get { return (ViewBase)GetValue(ViewProperty); }
            set { SetValue(ViewProperty, value); }
        }

        public static readonly DependencyProperty ViewProperty =
            DependencyProperty.Register("View", typeof(ViewBase), typeof(TreeListView));
}

2.2 在TreeListView控件模板中處理列頭

為了在TreeListView中顯示列頭,需要在合適的位置添加GridViewHeaderRowPresenter控件,并在Columns屬性上綁定我們之前定義的View.Columns屬性。下面我們首先來分析TreeView控件模板的代碼。

<ControlTemplate TargetType="{x:Type TreeView}">
    <Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels="true">
        <ScrollViewer x:Name="_tv_scrollviewer_" Background="{TemplateBinding Background}" CanContentScroll="false" Focusable="false" HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}">
            <ItemsPresenter/>
        </ScrollViewer>
    </Border>
    <ControlTemplate.Triggers>
        <Trigger Property="IsEnabled" Value="false">
            <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
        </Trigger>
        <Trigger Property="VirtualizingPanel.IsVirtualizing" Value="true">
            <Setter Property="CanContentScroll" TargetName="_tv_scrollviewer_" Value="true"/>
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

通過以上代碼我們可以看出,只要將GridViewHeaderRowPresenter控件添加到ScrollViewer控件上面即可實(shí)現(xiàn)列頭功能,但這樣會(huì)有一個(gè)問題,那就是內(nèi)容寬度超出控件寬度后,鼠標(biāo)拖動(dòng)橫向滾動(dòng)條時(shí)列頭不會(huì)跟隨下方的數(shù)據(jù)列表一起滾動(dòng)。為解決這個(gè)問題我們需要將GridViewHeaderRowPresenter放置到ScrollViewer控件模板中,以下為完整代碼。

<Style x:Key="{x:Static GridView.GridViewScrollViewerStyleKey}" TargetType="{x:Type ScrollViewer}">
    <Setter Property="Focusable" Value="false" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ScrollViewer}">
                <Grid Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*" />
                        <ColumnDefinition Width="Auto" />
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="*" />
                        <RowDefinition Height="Auto" />
                    </Grid.RowDefinitions>

                    <DockPanel Margin="{TemplateBinding Padding}">
                        <ScrollViewer
                                DockPanel.Dock="Top"
                                Focusable="false"
                                HorizontalScrollBarVisibility="Hidden"
                                VerticalScrollBarVisibility="Hidden">
                            <GridViewHeaderRowPresenter
                                    Margin="2,0,2,0"
                                    AllowsColumnReorder="{Binding TemplatedParent.View.AllowsColumnReorder, RelativeSource={RelativeSource TemplatedParent}}"
                                    ColumnHeaderContainerStyle="{Binding TemplatedParent.View.ColumnHeaderContainerStyle, RelativeSource={RelativeSource TemplatedParent}}"
                                    ColumnHeaderContextMenu="{Binding TemplatedParent.View.ColumnHeaderContextMenu, RelativeSource={RelativeSource TemplatedParent}}"
                                    ColumnHeaderStringFormat="{Binding TemplatedParent.View.ColumnHeaderStringFormat, RelativeSource={RelativeSource TemplatedParent}}"
                                    ColumnHeaderTemplate="{Binding TemplatedParent.View.ColumnHeaderTemplate, RelativeSource={RelativeSource TemplatedParent}}"
                                    ColumnHeaderTemplateSelector="{Binding TemplatedParent.View.ColumnHeaderTemplateSelector, RelativeSource={RelativeSource TemplatedParent}}"
                                    ColumnHeaderToolTip="{Binding TemplatedParent.View.ColumnHeaderToolTip, RelativeSource={RelativeSource TemplatedParent}}"
                                    Columns="{Binding TemplatedParent.View.Columns, RelativeSource={RelativeSource TemplatedParent}}"
                                    SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
                        </ScrollViewer>
                        <ScrollContentPresenter
                                x:Name="PART_ScrollContentPresenter"
                                CanContentScroll="{TemplateBinding CanContentScroll}"
                                Content="{TemplateBinding Content}"
                                ContentTemplate="{TemplateBinding ContentTemplate}"
                                KeyboardNavigation.DirectionalNavigation="Local"
                                SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
                    </DockPanel>

                    <ScrollBar
                            x:Name="PART_HorizontalScrollBar"
                            Grid.Row="1"
                            Cursor="Arrow"
                            Maximum="{TemplateBinding ScrollableWidth}"
                            Minimum="0.0"
                            Orientation="Horizontal"
                            ViewportSize="{TemplateBinding ViewportWidth}"
                            Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"
                            Value="{Binding HorizontalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" />
                    <ScrollBar
                            x:Name="PART_VerticalScrollBar"
                            Grid.Column="1"
                            Cursor="Arrow"
                            Maximum="{TemplateBinding ScrollableHeight}"
                            Minimum="0.0"
                            Orientation="Vertical"
                            ViewportSize="{TemplateBinding ViewportHeight}"
                            Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"
                            Value="{Binding VerticalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" />
                    <DockPanel
                            Grid.Row="1"
                            Grid.Column="1"
                            Background="{Binding Background, ElementName=PART_VerticalScrollBar}"
                            LastChildFill="false">
                        <Rectangle
                                Width="1"
                                DockPanel.Dock="Left"
                                Fill="White"
                                Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" />
                        <Rectangle
                                Height="1"
                                DockPanel.Dock="Top"
                                Fill="White"
                                Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" />
                    </DockPanel>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

<Style TargetType="{x:Type local:TreeListView}">
    <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto" />
    <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" />
    <Setter Property="ScrollViewer.CanContentScroll" Value="true" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:TreeListView}">
                <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
                    <ScrollViewer Padding="{TemplateBinding Padding}" Style="{StaticResource {x:Static GridView.GridViewScrollViewerStyleKey}}">
                        <ItemsPresenter />
                    </ScrollViewer>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

2.3 在TreeListViewItem模板中處理子項(xiàng)的展開和收縮

新建一個(gè)繼承自TreeViewItem的類,命名為TreeListViewItem(如有個(gè)性化需求,可以在該類中處理),編輯控件模板,在模板中添加以下代碼。

<Style TargetType="{x:Type local:TreeListViewItem}">
    <Setter Property="BorderThickness" Value="1" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:TreeListViewItem}">
                <StackPanel>
                    <Border
                            Name="Bd"
                            Padding="{TemplateBinding Padding}"
                            Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}">
                        <GridViewRowPresenter
                                x:Name="PART_Header"
                                Columns="{Binding RelativeSource={RelativeSource AncestorType=local:TreeListView}, Path=View.Columns}"
                                Content="{TemplateBinding Header}" />
                    </Border>
                    <ItemsPresenter x:Name="ItemsHost" />
                </StackPanel>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsExpanded" Value="false">
                        <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
                    </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>

                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="extensions:TreeViewItemExtensions.IsMouseDirectlyOverItem" Value="True" />
                        </MultiTrigger.Conditions>
                        <Setter TargetName="Bd" Property="Background" Value="{StaticResource Item.MouseOver.Background}" />
                        <Setter TargetName="Bd" Property="BorderBrush" Value="{StaticResource Item.MouseOver.Border}" />
                    </MultiTrigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="Selector.IsSelectionActive" Value="False" />
                            <Condition Property="IsSelected" Value="True" />
                        </MultiTrigger.Conditions>
                        <Setter TargetName="Bd" Property="Background" Value="{StaticResource Item.SelectedInactive.Background}" />
                        <Setter TargetName="Bd" Property="BorderBrush" Value="{StaticResource Item.SelectedInactive.Border}" />
                    </MultiTrigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="Selector.IsSelectionActive" Value="True" />
                            <Condition Property="IsSelected" Value="True" />
                        </MultiTrigger.Conditions>
                        <Setter TargetName="Bd" Property="Background" Value="{StaticResource Item.SelectedActive.Background}" />
                        <Setter TargetName="Bd" Property="BorderBrush" Value="{StaticResource Item.SelectedActive.Border}" />
                    </MultiTrigger>
                    <Trigger Property="IsEnabled" Value="False">
                        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

此處的核心在于模板中添加了GridViewRowPresenter控件,并在Columns屬性上綁定了我們之前定義的View.Columns屬性,這樣就可以在每一行上面顯示列數(shù)據(jù)。還有一個(gè)關(guān)鍵點(diǎn)是ItemsPresenter,它用于顯示子項(xiàng)數(shù)據(jù),此處命名為ItemsHost,它由屬性觸發(fā)器中的代碼來控件展開和收起。以下是屬性觸發(fā)器代碼。

<Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger>

2.4 在單元格模板中控件子項(xiàng)的展開與收起

為了達(dá)到展開和收起的效果,需要在首列的單元格中控制TreeListViewItem的IsExpanded屬性。以下為完整代碼。

<DataTemplate x:Key="ExpandCellTemplate">
    <DockPanel>
        <ToggleButton
                            x:Name="Expander"
                            Margin="{Binding Path=Level, Converter={StaticResource LevelIndentConverter}, RelativeSource={RelativeSource AncestorType={x:Type TreeListViewItem}}}"
                            ClickMode="Press"
                            IsChecked="{Binding Path=IsExpanded, RelativeSource={RelativeSource AncestorType={x:Type TreeListViewItem}}}"
                            Style="{StaticResource ExpandCollapseToggleStyle}" />
        <TextBlock Text="{Binding Property1}" />
    </DockPanel>
    <DataTemplate.Triggers>
        <DataTrigger Binding="{Binding Path=HasItems, RelativeSource={RelativeSource AncestorType={x:Type TreeListViewItem}}}" Value="False">
            <Setter TargetName="Expander" Property="Visibility" Value="Hidden" />
        </DataTrigger>
    </DataTemplate.Triggers>
</DataTemplate>

其關(guān)鍵代碼為

IsChecked="{Binding Path=IsExpanded, RelativeSource={RelativeSource AncestorType={x:Type TreeListViewItem}}}"

2.5 控件使用

<TreeListView ItemsSource="{Binding Collection}">
    <TreeListView.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Binding Collection, IsAsync=True}" />
    </TreeListView.ItemTemplate>
    <TreeListView.View>
        <GridView>
            <GridViewColumn CellTemplate="{StaticResource ExpandCellTemplate}" Header="Property1" />
            <GridViewColumn DisplayMemberBinding="{Binding Property2}" Header="Property2" />
            <GridViewColumn DisplayMemberBinding="{Binding Property3}" Header="Property3" />
            <GridViewColumn DisplayMemberBinding="{Binding Property4}" Header="Property4" />
            <GridViewColumn DisplayMemberBinding="{Binding Property5}" Header="Property5" />
            <GridViewColumn DisplayMemberBinding="{Binding Property6}" Header="Property6" />
            <GridViewColumn DisplayMemberBinding="{Binding Property7}" Header="Property7" />
            <GridViewColumn DisplayMemberBinding="{Binding Property8}" Header="Property8" />
            <GridViewColumn DisplayMemberBinding="{Binding Property9}" Header="Property9" />
            <GridViewColumn DisplayMemberBinding="{Binding Property10}" Header="Property10" />
            <GridViewColumn DisplayMemberBinding="{Binding Property11}" Header="Property11" />
            <GridViewColumn DisplayMemberBinding="{Binding Property12}" Header="Property12" />
        </GridView>
    </TreeListView.View>
</TreeListView>

以上就是WPF實(shí)現(xiàn)樹形表格控件的示例代碼的詳細(xì)內(nèi)容,更多關(guān)于WPF樹形表格控件的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C#刪除Word中的頁(yè)眉或頁(yè)腳的操作代碼

    C#刪除Word中的頁(yè)眉或頁(yè)腳的操作代碼

    在處理Word文檔批量操作時(shí),我們經(jīng)常需要清除頁(yè)眉頁(yè)腳——比如合并文檔后去除冗余信息,或?yàn)闃?biāo)準(zhǔn)化報(bào)告格式,手動(dòng)操作不僅繁瑣,更難以集成到自動(dòng)化流程中,所以本文給大家介紹了C#刪除Word中的頁(yè)眉或頁(yè)腳的操作方法,需要的朋友可以參考下
    2025-08-08
  • C#中?,??,??=,?:?,?.?,?[]各種問號(hào)的用法和說明詳解

    C#中?,??,??=,?:?,?.?,?[]各種問號(hào)的用法和說明詳解

    這篇文章主要介紹了C#中?、??、??=、?:、?.、?[]六種問號(hào)的用法和說明,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2025-11-11
  • C#實(shí)現(xiàn)文件Move和Copy操作

    C#實(shí)現(xiàn)文件Move和Copy操作

    這篇文章介紹了C#實(shí)現(xiàn)文件Move和Copy操作的方法,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-04-04
  • C# HttpClient Post參數(shù)同時(shí)上傳文件的實(shí)現(xiàn)

    C# HttpClient Post參數(shù)同時(shí)上傳文件的實(shí)現(xiàn)

    這篇文章主要介紹了C# HttpClient Post參數(shù)同時(shí)上傳文件的實(shí)現(xiàn),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • 關(guān)于C#中yield關(guān)鍵字的深入解析

    關(guān)于C#中yield關(guān)鍵字的深入解析

    這篇文章主要給大家介紹了關(guān)于C#中yield關(guān)鍵字的深入解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者使用C#具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • IIS下調(diào)用證書出現(xiàn)異常的解決方法 (C#)

    IIS下調(diào)用證書出現(xiàn)異常的解決方法 (C#)

    這篇文章主要為大家詳細(xì)介紹了IIS下調(diào)用證書出現(xiàn)異常的解決方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • C#如何創(chuàng)建自定義特性

    C#如何創(chuàng)建自定義特性

    這篇文章主要介紹了C#如何創(chuàng)建自定義特性,幫助大家更好的理解和學(xué)習(xí)使用c#,感興趣的朋友可以了解下
    2021-04-04
  • C#利用ReportViewer生成報(bào)表

    C#利用ReportViewer生成報(bào)表

    這篇文章主要為大家詳細(xì)介紹了C#利用ReportViewer生成報(bào)表的相關(guān)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • C#對(duì)XtraGrid控件實(shí)現(xiàn)主從表關(guān)系綁定

    C#對(duì)XtraGrid控件實(shí)現(xiàn)主從表關(guān)系綁定

    這篇文章介紹了C#對(duì)XtraGrid控件實(shí)現(xiàn)主從表關(guān)系綁定的方法,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-06-06
  • C#中字符串拼接方式及其性能分析對(duì)比

    C#中字符串拼接方式及其性能分析對(duì)比

    在C#編程中字符串拼接是一種常見且基礎(chǔ)的操作,廣泛應(yīng)用于各種場(chǎng)景,如動(dòng)態(tài)生成SQL查詢,構(gòu)建日志信息等,本文為大家整理了C#中字符串拼接的常見6種方式及其使用BenchmarkDotNet進(jìn)行性能分析對(duì)比,需要的可以參考下
    2024-12-12

最新評(píng)論

镇远县| 平利县| 南通市| 田林县| 井研县| 奉贤区| 衡东县| 达州市| 尼木县| 高陵县| 连云港市| 华宁县| 容城县| 南投县| 莆田市| 寿宁县| 虹口区| 东辽县| 西青区| 延边| 城步| 惠水县| 荥阳市| 镇江市| 嘉义市| 宝兴县| 泗阳县| 霍城县| 梧州市| 乌兰察布市| 清河县| 社旗县| 张家口市| 阿荣旗| 布拖县| 建德市| 纳雍县| 开鲁县| 祁东县| 聂拉木县| 雷山县|