• 有关Silverlight TreeView组件的研究[2]


    二、带复选框的TreeView

    说明:在TreeView中设置复选框是十分常见的,这有助于我们对于同组数据的一次性选取或取消。本文就将为你介绍怎样在Silverlight中实现带有Checkbox的TreeView。

    最初的步骤

    ObjectCollection

    这是Silverlight Toolkit 提供的一个对象集合,用以提供静态的对象资源绑定。注意:使用时一定要添加System.Windows.Controls.Toolkit的引用。在Skysigal上有一篇介绍静态资源数据绑定的好文章[链接],推荐给大家。

    HierarchicalDataTemplate

    这是用于处理层次状数据而设置的数据模板,其主要用于具有HeaderedItemsControl的组件,比如说TreeViewItem。详细内容请参考这里

    INotifyPropertyChanged

    向客户端发出某一属性值已更改的通知。主要用于实现数据的双向绑定。详细内容请参考这里

    实现业务对象Feature

    通过实现该业务对象,将能使其与TreeView进行交互。构建起这一对象的步骤主要有下述几步:

    第一,声明可在XAML文件中显示的内容属性,添加属性标签[ContentProperty("SubComponents")]。

    第二,使Feature对象继承接口INotifyPropertyChanged。

    第三,设定Feature对象的属性。

    第四,添加实现Checkbox效果的重要属性HasSubcomponents和ShouldInstall。

    第五,实现接口INotifyPropertyChanged定义的函数。

    具体代码请见下文。

    具体部署组件

    在MainPage.xaml文件中添加Feature对象的ObjectCollection资源,添加代表Feature对象Item的模板,以及添加有关数据对象的资源绑定。在MainPage.xaml.cs文件中添加对于TreeView组件的事件处理函数。具体代码请见下文。


    实例

    效果图




    代码段

    Feature业务对象代码(Feature.cs)

    using System.Collections.ObjectModel;

    using System.ComponentModel;

    using System.Windows.Markup;

     

    namespace SilverlightClient

    {

        [ContentProperty("Subcomponents")] //声明可在XAML文件中显示的内容属性

        public class Feature : INotifyPropertyChanged //继承接口INotifyPropertyChanged用于双向数据绑定

        {

            //Feature对象的属性

            public string FeatureName { get; set; }

            public string Description { get; set; }

     

            //声明全局变量

            public Collection<Feature> Subcomponents { get; private set; }

            private bool? _shouldInstall;

     

            //是否有子组件

            public bool HasSubcomponents

            {

                get

                {

                    return Subcomponents.Count > 0;

                }

            }

           

            //是否允许Feature进行安置

            public bool? ShouldInstall

            {

                get

                {

                    return _shouldInstall;

                }

                set

                {

                    if (value != _shouldInstall)

                    {

                        _shouldInstall = value;

                        OnPropertyChanged("ShouldInstall");

                    }

                }

            }

     

            //构造函数

            public Feature()

            {

                Subcomponents = new Collection<Feature>();

                ShouldInstall = true;

            }

     

            //事件委托

            public event PropertyChangedEventHandler PropertyChanged;

     

            //实现接口INotifyPropertyChanged定义函数

            private void OnPropertyChanged(string propertyName)

            {

                PropertyChangedEventHandler handler = PropertyChanged;

                if (null != handler)

                {

                    handler.Invoke(this, new PropertyChangedEventArgs(propertyName));

                }

            }

        }

    }

    MainPage.xaml代码

    <UserControl

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

        xmlns:toolkit="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Toolkit"

        xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"

        xmlns:common="clr-namespace:System.Windows;assembly=System.Windows.Controls"

        xmlns:samplesCommon="clr-namespace:SilverlightClient"

        mc:Ignorable="d" x:Class="SilverlightClient.MainPage"

        Width="640" Height="480">

     <Grid x:Name="LayoutRoot" Background="White" Width="640" Height="480">

            <StackPanel>

                <StackPanel.Resources>

                    <!-- 用于安置的示例Features -->

                    <toolkit:ObjectCollection x:Key="CorporationFeatures">

                        <samplesCommon:Feature FeatureName="公司部门" Description="公司各部门的结构">

                            <samplesCommon:Feature FeatureName="建筑部" Description="负责公司的工程项目">

                                <samplesCommon:Feature FeatureName="设计科" Description="负责项目的设计" />

                                <samplesCommon:Feature FeatureName="工程科" Description="负责项目的具体实施" />

                            </samplesCommon:Feature>

                            <samplesCommon:Feature FeatureName="管理部" Description="负责管理公司的财务与人事">

                                <samplesCommon:Feature FeatureName="财务科" Description="负责公司的对内对外的财务事宜" />

                                <samplesCommon:Feature FeatureName="总务人事科" Description="负责公司日常事务及员工招聘" />

                            </samplesCommon:Feature>

                        </samplesCommon:Feature>

                    </toolkit:ObjectCollection>

     

                    <!-- 代表一个Feature项的模板 -->

                    <common:HierarchicalDataTemplate x:Key="NodeTemplate" ItemsSource="{Binding Subcomponents}">

                        <StackPanel Orientation="Horizontal" ToolTipService.ToolTip="{Binding Description}">

                            <CheckBox

                            IsTabStop="False"                       

                            IsThreeState="{Binding HasSubcomponents}"

                            IsChecked="{Binding ShouldInstall, Mode=TwoWay}"

                            Click="ItemCheckbox_Click"

                            />

                            <ContentPresenter Content="{Binding FeatureName}" />

                        </StackPanel>

                    </common:HierarchicalDataTemplate>

                </StackPanel.Resources>

     

                <Grid>

                    <Grid.ColumnDefinitions>

                        <ColumnDefinition Width="*" />

                        <ColumnDefinition Width="2*" />

                    </Grid.ColumnDefinitions>

     

                    <controls:TreeView

                    Grid.Column="0"               

                    ItemTemplate="{StaticResource NodeTemplate}"

                    ItemsSource="{StaticResource CorporationFeatures}" FontSize="14">

     

                        <!-- 用来一次展开TreeView所有结点 -->

                        <controls:TreeView.ItemContainerStyle>

                            <Style TargetType="controls:TreeViewItem">

                                <Setter Property="IsExpanded" Value="True" />

                            </Style>

                        </controls:TreeView.ItemContainerStyle>

                    </controls:TreeView>

                   

                </Grid>

            </StackPanel>

        </Grid>

    </UserControl>

    MainPage.xaml.cs代码

    using System;

    using System.Collections.Generic;

    using System.Linq;

    using System.Net;

    using System.Windows;

    using System.Windows.Controls;

    using System.Windows.Documents;

    using System.Windows.Input;

    using System.Windows.Media;

    using System.Windows.Media.Animation;

    using System.Windows.Shapes;

     

    namespace SilverlightClient

    {

        public partial class MainPage : UserControl

        {

            public MainPage()

            {

                InitializeComponent();

            }

     

            //处理Checkbox点击事件

            private void ItemCheckbox_Click(object sender, RoutedEventArgs e)

            {

                TreeViewItem item = GetParentTreeViewItem((DependencyObject)sender);

                if (item != null)

                {

                    Feature feature = item.DataContext as Feature;

                    if (feature != null)

                    {

                        UpdateChildrenCheckedState(feature);//更新子组件选中状态

                        UpdateParentCheckedState(item);//更新父组件选中状态

                    }

                }

            }

           

            //静态方法:获取父级TreeViewItem

            private static TreeViewItem GetParentTreeViewItem(DependencyObject item)

            {

                if (item != null)

                {

                    DependencyObject parent = VisualTreeHelper.GetParent(item);//获取依赖的父级对象

                    TreeViewItem parentTreeViewItem = parent as TreeViewItem;//对象转换

                    return (parentTreeViewItem != null) ? parentTreeViewItem : GetParentTreeViewItem(parent);//如果父级TreeViewItem存在则返回,否则就递归寻找

                }

                //找不到父对象,返回父对象不存在

                return null;

            }

           

            //静态方法:更新父级TreeViewItem选中状态

            private static void UpdateParentCheckedState(TreeViewItem item)

            {

                TreeViewItem parent = GetParentTreeViewItem(item);//获取父级TreeViewItem

                if (parent != null)//如果父对象不为空,为空则退出递归寻找

                {

                    Feature feature = parent.DataContext as Feature;//对象转换

                    if (feature != null)//如果对象不为空

                    {

                        //更新子组件的选中状态

                        bool? childrenCheckedState = feature.Subcomponents.First<Feature>().ShouldInstall;//得到第一个子组件的选中状态

                        for (int i = 1; i < feature.Subcomponents.Count(); i++)

                        {

                            if (childrenCheckedState != feature.Subcomponents[i].ShouldInstall)

                            {

                                childrenCheckedState = null;

                                break;

                            }

                        }

     

                        //将父组件的选中状态与子组件置为相同

                        feature.ShouldInstall = childrenCheckedState;

     

                        //继续递归搜索.

                        UpdateParentCheckedState(parent);

                    }

                }

            }

     

            //用递归更新子组件的选中状态

            private static void UpdateChildrenCheckedState(Feature feature)

            {

                if (feature.ShouldInstall.HasValue)

                {

                    foreach (Feature childFeature in feature.Subcomponents)

                    {

                        childFeature.ShouldInstall = feature.ShouldInstall;

                        if (childFeature.Subcomponents.Count() > 0)

                        {

                            UpdateChildrenCheckedState(childFeature);

                        }

                    }

                }

            }

     

       }

  • 相关阅读:
    【Flutter学习】页面布局之基础布局组件
    【Flutter学习】基本组件之AppBar顶部导航栏
    【Flutter学习】基本组件之BottomNavigationBar底部导航栏
    开发日记:JsonCSharpHelp
    会议抢订
    C# WinForm 技巧十: winfrom 全屏自适应屏幕分辨率
    阿里云 轻量应用服务器(LAMP) 使用日志记录
    常见模块设计--权限管理(auth)
    PHP获取项目所有控制器方法名称
    想要开发自己的PHP框架需要那些知识储备?
  • 原文地址:https://www.cnblogs.com/bingyun84/p/1556038.html
Copyright © 2020-2023  润新知