展示树与devPress

这两天正在建树。


目标有几个:

1. 信息在数据库中,程序自动装载。

2. 表要少,特别是数据信息只在一个表中为好。因为目前的程序分三种:

1) 演示程序,信息在xml 文件中为好。随时都能展示给其它人看。

2)小客户端程序,不需要连远端数据库,用本地的access数据库就可以工作。

3)客户端工作在连接远端数据库的情况下。


也就是说,基础信息,有可能从远端同步到本地。

所以,表要少。


而且,树的层级关系,目前来看,不同的被管对象是不对的,是动态变化的,我们不能说哪一层,具有什么特定的含义,所以,要建一个子从属于父的关联树。


然后,展示到界面上。


小团队开发,或是一个人开发,象我这样,最好先考虑界面。因为界面是工作量最大的,内存结构做得好,可不一定界面上就好显示。


一开始调研了一个小程序: HierarchyTree

http://www.codeproject.com/script/articles/download.aspx?file=/KB/aspnet/HierarchyTree/HierarchyTree.zip&rp=http://www.codeproject.com/Articles/140827/Dynamic-Binding-Of-Hierarchy-Data-Structure-To-Tre


这个例子,展示了一种通常的作法。

但从各个方面,我不喜欢。看来在C#里面处理树不是很方便。当然,也是作者没有写好。


      foreach (HierarchyTrees.HTree hTree in hierarchyTrees)     
        {
            HierarchyTrees.HTree parentNode = hierarchyTrees.Find(delegate(HierarchyTrees.HTree emp) { return emp.NodeID == hTree.UnderParent; });
            if (parentNode != null)
            {         
                foreach (TreeNode tn in tvHierarchyView.Nodes)
                {
                    if (tn.Value == parentNode.NodeID.ToString())
                    {
                        tn.ChildNodes.Add(new TreeNode(hTree.NodeDescription.ToString(), hTree.NodeID.ToString()));
                        
                    }
                    if (tn.ChildNodes.Count > 0)
                    {
                        foreach (TreeNode ctn in tn.ChildNodes)
                        {
                            //RecursiveChild(ctn, parentNode.NodeID.ToString(), hTree);
                        }
                    }
                }                
            }
            else
            {               
                tvHierarchyView.Nodes.Add(new TreeNode(hTree.NodeDescription, hTree.NodeID.ToString()));
            } 
            }     
        tvHierarchyView.ExpandAll(); 
    }


这里我们看到,作者进行了两次迭代。比较糟的做法。

通常来讲,应当几步:

1) 在内存中建树。

2) 插入到界面。

插入界面的过程,有两个功能,需要注意:一个是在内存树中,如何遍历,如何快速定位。

一个是在界面树中,如何快速定位。

所以,在建内存数,和插入界面的时候,应当伴随建一个hash 表,或是快速map 之类的,两棵树都要有。

否则,代码就这成这位兄台这样:看起来很短,但究其实质,很糟。


为什么两步呢?以前我很喜欢一步到位,这样好处是,不用自己建树了,直接用界面控件的树就好了。不能说不好,因为这样有一个很重要的好处:不需要进行内存与界面的同步工作。对于动态树,这的确是要小心处理的,如果内存树还有界面树又分别建了索引,同步的工作量,还是有的。


但,编程,一味图快,图简单,问题也多。因为程序和人一样,是要腐烂的。总有一天,作者本人也不想闻一闻,究其原因,就是语义不清。

有了良好的内存结构,意味着复用性好:一方面,本程序内,其它模块好利用,另一方面这些代码,也便于复用到其它的项目中。


=============

本着这样的意图。我再次开始了脑子。


一般而言,大公司做的东西相对好一些。所以,我找到devExpress中的例子,花了大半天时间,建环境。

因为要跟代码。

看的例子是这个:用的是DX2011.2.5_src

XtraTreeList

刚接个电话,闲话少说吧,

这个例子,是从一个xml中读取信息,放到界面上。

可以猜测,一定有两个固有的字段:

ID

ParentID

这里,我再强调一下关键是你要有原码。看原码比一切理论都有实际意义。

另外,一定要建好调试环境。因为我手头的devExpress原码,也搞不清楚是从哪拿的,没有注释,可能这也是devexpress公司的策略,他们不会发布有注释的原码。

但也足够了。


至于,如何建这种环境,以后我来讲解。接了两个电话,已超时了。


<?xml version="1.0" standalone="yes"?>
<NewDataSet>
  <xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xs:element name="NewDataSet" msdata:IsDataSet="true">
      <xs:complexType>
        <xs:choice maxOccurs="unbounded">
          <xs:element name="Table">
            <xs:complexType>
              <xs:sequence>
                <xs:element name="Id" type="xs:double" minOccurs="0" />
                <xs:element name="ParentId" type="xs:double" minOccurs="0" />
		<xs:element name="FirstName" type="xs:string" minOccurs="0" />
		<xs:element name="LastName" type="xs:string" minOccurs="0" />
		<xs:element name="JobTitle" type="xs:string" minOccurs="0" />
		<xs:element name="Phone" type="xs:string" minOccurs="0" />
		<xs:element name="EmailAddress" type="xs:string" minOccurs="0" />
		<xs:element name="AddressLine1" type="xs:string" minOccurs="0" />
		<xs:element name="City" type="xs:string" minOccurs="0" />
		<xs:element name="PostalCode" type="xs:string" minOccurs="0" />
		<xs:element name="CountryRegionName" type="xs:string" minOccurs="0" />
		<xs:element name="StateProvinceName" type="xs:string" minOccurs="0" />
		<xs:element name="GroupName" type="xs:string" minOccurs="0" />
		<xs:element name="BirthDate" type="xs:dateTime" minOccurs="0" />
		<xs:element name="HireDate" type="xs:dateTime" minOccurs="0" />
		<xs:element name="Gender" type="xs:string" minOccurs="0" />
		<xs:element name="MaritalStatus" type="xs:string" minOccurs="0" />
		<xs:element name="Title" type="xs:string" minOccurs="0" />
              </xs:sequence>
            </xs:complexType>
          </xs:element>
        </xs:choice>
      </xs:complexType>
    </xs:element>  
  </xs:schema>
<Table>
    <Id>109</Id>
    <ParentId>0</ParentId>
    <FirstName>Bruce</FirstName>
    <LastName>Cambell</LastName>
    <JobTitle>Chief Executive Officer</JobTitle>
    <Phone>(417) 166-3268</Phone>
    <EmailAddress>Bruce_Cambell@example.com</EmailAddress>
    <AddressLine1>4228 S National Ave</AddressLine1>
    <City>Oaks</City>
    <PostalCode>65809</PostalCode>
    <StateProvinceName>California</StateProvinceName>
    <CountryRegionName>United States</CountryRegionName>
    <GroupName>Executive General and Administration</GroupName>
    <BirthDate>1957-09-06T00:00:00</BirthDate>
    <HireDate>2000-07-02T00:00:00</HireDate>
    <Gender>M</Gender>
    <MaritalStatus>M</MaritalStatus>
    <Title>Mr.</Title>
  </Table>
  <Table>
    <Id>42</Id>
    <ParentId>109</ParentId>
    <FirstName>Cindy</FirstName>
    <LastName>Haneline</LastName>
    <JobTitle>Information Services Manager</JobTitle>
    <Phone>(918) 161-3649</Phone>
    <EmailAddress>Cindy_Haneline@example.com</EmailAddress>
    <AddressLine1>2429 E. 15th Street</AddressLine1>
    <City>Vista</City>
    <PostalCode>74014</PostalCode>
    <StateProvinceName>California</StateProvinceName>
    <CountryRegionName>United States</CountryRegionName>
    <GroupName>Executive General and Administration</GroupName>
    <BirthDate>1973-12-23T00:00:00</BirthDate>
    <HireDate>1996-11-06T00:00:00</HireDate>
    <Gender>F</Gender>
    <MaritalStatus>S</MaritalStatus>
  </Table>



============

好了,开始。


DX2011.2.5_src\Sources\DevExpress.XtraTreeList\DevExpress.XtraTreeList\TreeList.cs(692):   


        protected const string defKeyFieldName = "ID",
            defParentFieldName = "ParentID",
            defImageIndexFieldName = "ImageIndex";
        public TreeList() : this(null) {
        }

这是最关键的几句话,我一开始跟了半天,才找到,原来是写死的。

初始化:

namespace DevExpress.XtraTreeList.Demos {
    public partial class NodesFiltering : DevExpress.XtraTreeList.Demos.TutorialControl {
        public NodesFiltering() {
            InitializeComponent();
            InitData();
            InitEditors();
            //InitFilter();
            treeList1.Columns["pkgName"].AllNodesSummary = true;
            treeList1.Columns["pkgName"].SummaryFooter = SummaryItemType.Count;
            treeList1.Columns["pkgName"].OptionsFilter.FilterPopupMode = FilterPopupMode.CheckedList;
            treeList1.OptionsView.ShowSummaryFooter = true;
        }



这里,我们改一下,不从xml,改从sqlserver中读。

        private void InitData() {
            string DBFileName = DevExpress.Utils.FilesHelper.FindingFileName(Application.StartupPath, "Data\\Employees.xml");
            if(DBFileName != "") {
                DataSet dataSet = new DataSet();
                //dataSet.ReadXml(DBFileName);




                using (SqlConnection connection = new SqlConnection(@"Data Source=127.0.0.1;Initial Catalog=AutoPack;Persist Security Info=True;User ID=sa;Password=12345"))
                {
                    connection.Open();//SSP_GET_HIERARCHY
                    using (SqlCommand command = new SqlCommand("select * from TBL_TREE_HIERARCHY", connection))
                    {
                        //command.CommandType = System.Data.CommandType.StoredProcedure;
                        //SqlDataReader reader = command.ExecuteReader(System.Data.CommandBehavior.CloseConnection);


                        SqlDataAdapter da = new SqlDataAdapter(command);
                        //DataSet ds = new DataSet();
                        //fill the DataSet using default values for DataTable names, etc.

                        da.Fill(dataSet);
                    }
                }

                treeList1.DataSource = dataSet.Tables[0].DefaultView;
                treeList1.ForceInitialize();
                treeList1.ExpandAll();
                treeList1.BestFitColumns();
            }
        }


//这段代码,要是不处理,则确保表里有相关的字段:GroupName

        string currentGroupName;
        private void treeList1_GetStateImage(object sender, GetStateImageEventArgs e) {
            string[] groupNames = new string[] { "Administration", "Inventory", "Manufacturing", "Quality", "Research", "Sales" };
            currentGroupName =  (string)e.Node.GetValue("GroupName");
            e.NodeImageIndex = Array.FindIndex(groupNames, new Predicate<string>(IsCurrentGroupName));
        }
        private bool IsCurrentGroupName(string groupName) { return currentGroupName.Contains(groupName); }
 

数据库表如下:

USE [AutoPack]
GO

/****** Object:  Table [dbo].[TBL_TREE_HIERARCHY]    Script Date: 02/25/2014 17:45:37 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[TBL_TREE_HIERARCHY](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [ParentID] [int] NULL,
    [pkgName] [nvarchar](511) NULL,
    [NODE_DESCRIPTION] [nvarchar](511) NULL,
    [ImageIndex] [int] NULL,
    [UVERSION] [nvarchar](511) NULL,
    [VER] [nvarchar](511) NULL,
    [Title] [nvarchar](511) NULL,
    [GroupName] [nvarchar](511) NULL,
    [pkgFilename] [nvarchar](511) NULL
) ON [PRIMARY]

GO

内容,我随意写的
ID    ParentID    pkgName    NODE_DESCRIPTION    ImageIndex    UVERSION    VER    Title    GroupName    pkgFilename
1    0    a    Mathematics    0    A    1    wert    Administration    a.out
2    1    b    Algebra    NULL    A    2    fgg    Inventory    b.out
3    1    c    Geometry    0    A    3    s    Research    c.out
4    3    d    Triangle    0    A    1    ert    Research    d.out
5    4    e    By Relative Length    0    A    NULL    f    Research    e.out
6    4    f    By Internal Angle    0    A    232    s    Research    f.out
7    5    g    Equilateral Triangle    0    A    124    dfgwr    Research    g.out
8    5    h    Scalene Triangle    0    A    3    NULL    Quality    h.out
9    5    i    Isosceles Triangle    0    A    5    sfdg    Quality    i.out
10    6    j    Oblique > 90 Degree:Obtuse Angled Traingle    0    A    5    s    Quality    j.out
11    6    k    Oblique < 90 Degree:Acute Angled Traingle    0    A    5    f    Quality    k.out
12    6    l    Right Angled Triangle    0    A    4    sfg    Quality    l.out
13    2    m    Elementary Algebra    0    A    4    sf    Quality    m.out
14    2    n    Abstract Algebra    0    A    6    gsfgh    Manufacturing    n.out
15    2    o    Linear Algebra    0    A    345    fgj    Manufacturing    o.out
16    7    p    All Sides are Equal    0    A    3    fghj    Manufacturing    p.out


下一步,把这里改了在namespace DevExpress.XtraTreeList.Demos {
    partial class NodesFiltering {

...

            this.treeListColumn1.Caption = "包名称";
            this.treeListColumn1.FieldName = "pkgName";
            this.treeListColumn1.MinWidth = 33;
            this.treeListColumn1.Name = "treeListColumn1";
            this.treeListColumn1.Visible = true;
            this.treeListColumn1.VisibleIndex = 0;
            this.treeListColumn1.Width = 105;
            //
            // treeListColumn2
            //
            this.treeListColumn2.Caption = "文件名";
            this.treeListColumn2.FieldName = "pkgFilename";
            this.treeListColumn2.Name = "treeListColumn2";
            this.treeListColumn2.Visible = true;
            this.treeListColumn2.VisibleIndex = 1;
            this.treeListColumn2.Width = 106;


其它列删除

好了,跑起来,


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
用官方汉化包汉化DXperience控件详细步骤!! 1.你要先安装某一版本的DXperience控件(如:DXperience-11.2.5.exe)可以在这里http://www.devexpresscn.com/下载。 2.安装DXperience控件到某一目录下。(如:D:\DevExpress 11.2) 3.下载对应的汉包。(如:DXperience-11.2.5.exe的汉化包,名称为:dxKB_A421_DXperience_v11.2_(2012-04-27).zip)可以在http://www.devexpresscn.com/news/DevExpress-news-94.html下载。 4.解压汉包,在解压后的文件夹中找到DevExpress.DLL文件夹,在DevExpress.DLL文件夹中找到zh-CHS文件夹。 5.把zh-CHS文件夹复制到你建立的工程下的Debug文件夹中。(如 D:\Test\汉化Test\汉化Test\bin\Debug) 到这里汉化资源已经到位了。下面是在编程时使用汉化资源。(以C#为例) 6.在编程时,在Main方法中加入System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("zh-CHS");(C#中Main方法在Program.cs文件中) 比较: 加入前: using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; namespace 汉o化?¥Test { static class Program { /// <summary> /// 应?|用??程¨?序¨°的ì?主??入¨?口¨2点ì?。?ê /// </summary> [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); } } } 加入后: using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; namespace 汉o化?¥Test { static class Program { /// <summary> /// 应?|用??程¨?序¨°的ì?主??入¨?口¨2点ì?。?ê /// </summary> [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("zh-CHS"); Application.Run(new Form1()); } } } 到这汉化已经全部完成。接下来就是托控件了(使用控件)。如果你连托控件都不会,那么……我已被震亡了!! 说明:这个方法汉化不完全。(是官方汉化包的问题)
### 回答1: WinForms DevPress教程是一个面向开发人员的教程,旨在教授使用WinForms进行Windows桌面应用程序开发的技能。WinForms是一种广泛使用的用户界面框架,由Microsoft开发并集成到.NET框架中。 该教程提供了详细的指导和示例代码,帮助开发人员了解WinForms的基本概念、架构和工作原理。它涵盖了各种WinForms控件和布局管理器的使用方法,以及与其他.NET技术的集成,如ADO.NET数据库访问、ASP.NET网站开发和Windows服务等。 教程的内容涵盖了从入门到高级的所有知识点,逐步引导开发人员掌握WinForms开发的各个方面。它提供了丰富的实例,让开发人员能够亲自动手实践所学的知识,加深对WinForms的理解和应用。 通过学习WinForms DevPress教程,开发人员可以掌握创建功能丰富且用户友好的Windows应用程序的技能。他们可以学习如何设计和实现界面,处理用户输入,展示数据,处理事件,以及其他一系列与Windows应用程序开发相关的知识。 总的来说,WinForms DevPress教程是一份详尽而系统的教程,对于希望学习和掌握WinForms开发的开发人员来说,是一个宝贵的学习资源。无论是初学者还是有经验的开发人员,都可以通过这个教程提升自己的技能,并开发出高质量的Windows桌面应用程序。 ### 回答2: WinForm Devpress教程是一种针对WinForms开发的编程教程。它提供了深入的指导和示例,帮助开发者快速掌握WinForms框架的使用。 首先,WinForms是一种用于开发Windows桌面应用程序的技术。它提供了丰富的用户界面控件,使开发者能够轻松地构建各种功能强大的应用程序,包括窗口、对话框、按钮、文本框等。 WinForm Devpress教程通过详细的步骤和清晰的示例,引导开发者从基础知识到高级技术的学习。它从安装和设置开始,介绍了WinForms框架的核心概念和主要组件。然后,它深入讲解了如何创建窗体、添加控件、设计界面和布局,以及处理事件和实现交互功能。 此外,WinForm Devpress教程还介绍了与数据操作、文件处理、网络通信等相关的WinForms开发技术。它涵盖了数据绑定、ADO.NET、LINQ、文件I/O、Socket通信等内容,帮助开发者构建更复杂、功能更强大的应用程序。 WinForm Devpress教程的优点在于它的简洁明了,适合初学者入门使用。它提供了丰富的示例代码和实践项目,帮助开发者理解和应用所学知识。此外,它还提供了在线的支持和交流平台,让开发者能够与其他学习者交流和分享经验。 综上所述,WinForm Devpress教程是一种高质量的学习资源,它提供了全面而深入的WinForms开发教程,帮助开发者快速掌握WinForms框架,构建出各种功能丰富的Windows桌面应用程序。 ### 回答3: WinForms DevPress教程是一个针对Windows应用程序开发的教程系列。WinForms是一种用于创建Windows桌面应用程序的开发技术,而DevPress是一家知名的技术教程网站。 这个教程系列的目标是帮助开发者掌握WinForms开发技术,从而能够自己设计和编写Windows应用程序。教程从基本的WinForms概念开始,逐渐引导学习者了解各种控件、布局和事件处理,并提供了大量的实际示例和实践项目供学习者练习。 该教程的优点在于它的结构清晰、内容丰富且易于理解。它通过一步步的教学方式,帮助学习者逐渐建立起对WinForms开发的整体认识。教程中也包含了一些常见问题的解答和实用技巧,对于初学者来说非常有帮助。 此外,WinForms DevPress教程还提供了一些高级主题,包括自定义控件、数据绑定、多线程编程等等。这些高级主题能够帮助学习者提升自己的开发水平,更加深入地掌握WinForms技术。 总的来说,WinForms DevPress教程是一份非常实用和全面的教材,适合那些希望学习并掌握WinForms开发技术的开发者。它不仅能够帮助初学者从零开始学习,也能够帮助有一定经验的开发者提升自己的技能水平。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值