Silverlight Treeview 相关操作:加载,保存,索引节点,节点移动,模板节点(收藏)

     最近一个Silverlight项目中,需要多处表达展示内容的“父子”关系。自然用“树”来表达自然是再好不过。Ms Toolkit中包含了TreeView控件,很好的满足了需求。
     要表述树状关系,数据库的设计一定要合理,不然这层关系在加载的时候就会很痛苦。另外,根据需求,树状节点的展示还要有一定的顺序,所以一棵树在保存的时候,每个节点在树中的位置也要有所记录。
     数据库设计


CREATE TABLE BASIC_INFO
(
  ID        
NUMBER(22,3),
  NAME      
VARCHAR2(100 BYTE),
  PARENTID  
NUMBER(22,3),
  GRADE     
NUMBER(1),
  MEMO      
VARCHAR2(100 BYTE),
  IDX       
NUMBER(5)
)

     这样,加载的时候就可以根据ID,ParentID找到父子关系,并根据IDX来加载ID在树中的索引。这个索引要从树的第一个节点开始深度遍历,根据遍历到的节点的顺序记录其索引。

-树的加载

 string sqlTv = "SELECT * FROM PDM_BASIC_INFO ORDER BY IDX ASC";


void client_getProjectInfoCompleted(object sender, getProjectInfoCompletedEventArgs e)
        {
                      
if (e.Error == null)
            {
                tvshow.Items.Clear();

ObservableCollection
<ProjectInfo> listsForProject = new ObservableCollection<ProjectInfo>();

                listsForProject 
= e.Result;

                
//添加Title Node
                TreeViewItem titleNode = new TreeViewItem();
                titleNode.FontSize 
= 15;

               
//为树加载标题节点
                
//titleNode.Background = new SolidColorBrush(Colors.Cyan);
                Grid gridTitle = getTitleGridTemplate();
                setTitleData(gridTitle);
                titleNode.Header 
= gridTitle;

                
// titleNode.Background = null;
                tvshow.Items.Add(titleNode);


                
///加载添加Node
                AddTreeNodeForProject(0null);

            
            }
            
else
            {
                MessageBox.Show(
"操作异常,请重新作业" + e.Error.Message, "注意", MessageBoxButton.OK);
            }
        }

 


     private void AddTreeNodeForProject(int parentID, TreeViewItem treeViewItem)
        {

            List
<ProjectInfo> result = (from Info in listsForProject
                                        
where Info.ParentID == parentID
                                        select Info).ToList
<ProjectInfo>();

            
if (result.Count > 0)
            {
                
foreach (ProjectInfo info in result)
                {
                    TreeViewItem objTreeNode 
= new TreeViewItem();
                    objTreeNode.IsExpanded 
= true;
                   
                    
//如果是叶子节点,为其加载模板控制项
                    if (info.Grade == 3//叶子节点绑定 时间控制项
                       {
                        Grid grid 
= getGridTemplate();
                        setGridData(grid, info.Name, info.ID);
                        objTreeNode.Header 
= grid;

                    }
                    
else
                    {
                        objTreeNode.Header 
= "[" + info.ID + "]" + info.Name;
                    }

                    
//添加根节点
                    if (treeViewItem == null)
                    {
                        tvshow.Items.Add(objTreeNode);
                    }
                    
else
                    {
                        treeViewItem.Items.Add(objTreeNode);
                    }
                    
//递归加载
                    AddTreeNodeForProject(info.ID, objTreeNode);
                }
            }
        }

 

 其中,节点的header属性为object类型,这样我们可以根据需求,为其赋予需要的控制项。

设置定制节点

Code void setTitleData(Grid grid)
        {
            TextBlock Phase 
= new TextBlock();
            Phase.Text 
= "Phase";


            Grid.SetColumn(Phase, 
0);
            grid.Children.Add(Phase);

            Phase 
= new TextBlock();
            Phase.Text 
= "Task";

            Grid.SetColumn(Phase, 
1);
            grid.Children.Add(Phase);

            Phase 
= new TextBlock();
            Phase.Text 
= "Item";

            Grid.SetColumn(Phase, 
2);
            grid.Children.Add(Phase);

            Phase 
= new TextBlock();
            Phase.Text 
= "工期";

            Grid.SetColumn(Phase, 
3);
            grid.Children.Add(Phase);


            Phase 
= new TextBlock();
            Phase.Text 
= "开始时间";

            Grid.SetColumn(Phase, 
4);
            grid.Children.Add(Phase);

            Phase 
= new TextBlock();
            Phase.Text 
= "实际开始时间";

            Grid.SetColumn(Phase, 
5);
            grid.Children.Add(Phase);

            Phase 
= new TextBlock();
            Phase.Text 
= "完成时间";

            Grid.SetColumn(Phase, 
6);
            grid.Children.Add(Phase);

            Phase 
= new TextBlock();
            Phase.Text 
= "实际完成时间";

            Grid.SetColumn(Phase, 
7);
            grid.Children.Add(Phase);
        }

        
private void setGridData(Grid grid, string str, int id)
        {
            
//序号
            TextBlock flag = new TextBlock();
            flag.Tag 
= id;
            Grid.SetColumn(flag, 
0);
            grid.Children.Add(flag);

            
//名称
            TextBlock lbl = new TextBlock();
            lbl.Text 
= "[" + id.ToString() + "]" + str;
            
//lbl.Text = str;
            Grid.SetColumn(lbl, 1);
            grid.Children.Add(lbl);

            
//工期
            TextBox txt = new TextBox();
            txt.IsEnabled 
= false;
            Grid.SetColumn(txt, 
2);
            grid.Children.Add(txt);

            
//开始时间
            DatePicker dp = new DatePicker();
            dp.IsEnabled 
= false;
            Grid.SetColumn(dp, 
3);
            grid.Children.Add(dp);

            
//实际开始时间
            dp = new DatePicker();
            Grid.SetColumn(dp, 
4);
            grid.Children.Add(dp);


            
//完成时间
            dp = new DatePicker();
            dp.IsEnabled 
= false;
            Grid.SetColumn(dp, 
5);
            grid.Children.Add(dp);

            
//实际完成时间
            dp = new DatePicker();
            Grid.SetColumn(dp, 
6);
            grid.Children.Add(dp);

        }

        
private Grid getGridTemplate()
        {
            Grid grid 
= new Grid();
            RowDefinition row1 
= new RowDefinition();
            grid.RowDefinitions.Add(row1);

            
//id
            ColumnDefinition col = new ColumnDefinition();
            col.Width 
= new GridLength(1);
            grid.ColumnDefinitions.Add(col);

            
//ITem Name
            col = new ColumnDefinition();
            col.Width 
= new GridLength(250);
            grid.ColumnDefinitions.Add(col);

            
//工期
            col = new ColumnDefinition();
            col.Width 
= new GridLength(50);
            grid.ColumnDefinitions.Add(col);

            
//计划开始时间
            col = new ColumnDefinition();
            col.Width 
= new GridLength(150);
            grid.ColumnDefinitions.Add(col);

            
//实际开始时间
            col = new ColumnDefinition();
            col.Width 
= new GridLength(150);
            grid.ColumnDefinitions.Add(col);

            
//完成时间
            col = new ColumnDefinition();
            col.Width 
= new GridLength(150);
            grid.ColumnDefinitions.Add(col);

            
//实际完成时间
            col = new ColumnDefinition();
            col.Width 
= new GridLength(150);
            grid.ColumnDefinitions.Add(col);

            
return grid;
        }

        
private Grid getTitleGridTemplate()
        {
            Grid grid 
= new Grid();
            RowDefinition row1 
= new RowDefinition();

            grid.RowDefinitions.Add(row1);

            
//Phase
            ColumnDefinition col = new ColumnDefinition();
            col.Width 
= new GridLength(40);
            grid.ColumnDefinitions.Add(col);

            
//task
            col = new ColumnDefinition();
            col.Width 
= new GridLength(50);
            grid.ColumnDefinitions.Add(col);

            
//item
            col = new ColumnDefinition();
            col.Width 
= new GridLength(210);
            grid.ColumnDefinitions.Add(col);

            
//工期
            col = new ColumnDefinition();
            col.Width 
= new GridLength(50);
            grid.ColumnDefinitions.Add(col);

            
//计划开始时间
            col = new ColumnDefinition();
            col.Width 
= new GridLength(150);
            grid.ColumnDefinitions.Add(col);

            
//实际开始时间
            col = new ColumnDefinition();
            col.Width 
= new GridLength(150);
            grid.ColumnDefinitions.Add(col);

            
//计划完成时间
            col = new ColumnDefinition();
            col.Width 
= new GridLength(150);
            grid.ColumnDefinitions.Add(col);

            
//实际完成时间
            col = new ColumnDefinition();
            col.Width 
= new GridLength(150);
            grid.ColumnDefinitions.Add(col);

            
return grid;
        }

 Demo:

读取节点信息


for (int n = 0; n < items.Items.Count; n++//遍历ITems
                    {
                        TreeViewItem item 
= items.Items[n] as TreeViewItem;

                        Grid grid 
= item.Header as Grid;

                        TextBlock txtID 
= grid.Children[0as TextBlock;
                        DatePicker txtStart 
= grid.Children[4as DatePicker;
                        DatePicker txtEnd 
= grid.Children[6as DatePicker;
                    
                        
//code here

                    }

 

--=============
     另外,用户提出一些特定的需求:树状节点的顺序他们要自己调整。Liquid.Treeview控件,可以很好的实现节点的拖拽和移动,我们只需要在用户移动后深度遍历每个节点,并保存其位置索引信息即可。
    Liquid.Treeview节点的移动:


     Node node = tvshow.Selected;
            
if (node != null)
            {
                node.SwapPrevious();

                
// node.SwapNext();
            }


遍历保存节点索引


 ObservableCollection<PDMInfo> PDMInfos = new ObservableCollection<PDMInfo>();

            
int m = 0;

            PDMInfo info 
= new PDMInfo();

            
for (int i = 0; i < tvshow.Nodes.Count; i++//phase
            {
                Node phase 
= tvshow.Nodes[i] as Node;
                m 
= m + 1;

                
int PhaseID = Convert.ToInt32(phase.Tag);

                info 
= new PDMInfo()
                {
                    ID 
= PhaseID,
                    IDX 
= m
                };

                PDMInfos.Add(info);

                
for (int j = 0; j < phase.Nodes.Count; j++)
                {
                    Node task 
= phase.Nodes[j] as Node;

                    m 
= m + 1;
                    
int TaskID = Convert.ToInt32(task.Tag);

                    info 
= new PDMInfo()
                    {
                        ID 
= TaskID,
                        IDX 
= m
                    };

                    PDMInfos.Add(info);

                    
for (int n = 0; n < task.Nodes.Count; n++)
                    {
                        Node item 
= task.Nodes[n] as Node;

                        m 
= m + 1;
                        
int ItemID = Convert.ToInt32(item.Tag);

                        info 
= new PDMInfo()
                        {
                            ID 
= ItemID,
                            IDX 
= m
                        };

                        PDMInfos.Add(info);

                    }
                }
            }

            client.UpdatePDMInfoToDBCompleted 
+= new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(client_UpdatePDMInfoToDBCompleted);
            client.UpdatePDMInfoToDBAsync(PDMInfos);
posted @ 2009-03-20 10:47  yongbin621  阅读(430)  评论(1编辑  收藏  举报