当前位置:文档之家› silverlight TreeView

silverlight TreeView

silverlight TreeView
silverlight TreeView

Silverlight Treeview 相关操作:加载,保存,索引节点,节点

移动,模板节点

作者:Ivan-Yan来源:博客园发布时间:2009-03-14 08:42 阅读:3064 次原文链接[收藏]最近一个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, getProjectInfoComp letedEventArgs e)

{

if (e.Error == null)

{

tvshow.Items.Clear();

ObservableCollection listsForProject = new ObservableCol lection();

listsForProject = e.Result;

//添加Title Node

TreeViewItem titleNode = new TreeViewItem();

titleNode.FontSize = 15;

//为树加载标题节点

//titleNode.Background = new SolidColorBrush(Colors.C yan);

Grid gridTitle = getTitleGridTemplate();

setTitleData(gridTitle);

titleNode.Header = gridTitle;

// titleNode.Background = null;

tvshow.Items.Add(titleNode);

///加载添加Node

AddTreeNodeForProject(0, null);

}

else

{

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

}

}

private void AddTreeNodeForProject(int parentID, TreeViewItem tr eeViewItem)

{

List result = (from Info in listsForProject

where Info.ParentID == parent ID

select Info).ToList();

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, https://www.doczj.com/doc/7d2704850.html,, info.ID);

objTreeNode.Header = grid;

}

else

{

objTreeNode.Header = "[" + info.ID + "]" + in https://www.doczj.com/doc/7d2704850.html,;

}

//添加根节点

if (treeViewItem == null)

{

tvshow.Items.Add(objTreeNode);

}

else

{

treeViewItem.Items.Add(objTreeNode);

}

//递归加载

AddTreeNodeForProject(info.ID, objTreeNode);

}

}

}

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

设置定制节点

private 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 TreeVie wItem;

Grid grid = item.Header as Grid;

TextBlock txtID = grid.Children[0] as TextBlo ck;

DatePicker txtStart = grid.Children[4] as Dat ePicker;

DatePicker txtEnd = grid.Children[6] as DateP icker;

//code here

}

--=============

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

Liquid.Treeview节点的移动:

Node node = tvshow.Selected;

if (node != null)

{

node.SwapPrevious();

// node.SwapNext();

}

遍历保存节点索引

ObservableCollection PDMInfos = new ObservableCollection();

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(client_UpdatePDMInfoToDBC ompleted);

client.UpdatePDMInfoToDBAsync(PDMInfos);

WPF TreeView递归异步绑定(2)

时间:2011-05-06 04:09来源:CSDN学生大本营作者:Sonny 点击:354次

4)创建TreeView 的Model类DepartmentViewModel using System; using System.Collections.Generic; using System.Linq; using System.Text; using https://www.doczj.com/doc/7d2704850.html,ponentModel; using System.Collections.ObjectModel; na

4)创建TreeView 的Model类DepartmentViewModel

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using https://www.doczj.com/doc/7d2704850.html,ponentModel;

using System.Collections.ObjectModel;

namespace DepartmentTreeView {

public class DepartmentViewModel:INotifyPropertyChanged {

//临时子节点用,当Expanded时移除此节点,添加子节点

static readonly DepartmentViewModel _temp = new DepartmentViewModel( null);

//选中的子节点

private static ObservableCollection _checkedIte ms = new ObservableCollection();

//根节点

static DepartmentViewModel _rootItem;

#region fields&properties

private bool? _isChecked;

public bool? IsChecked {

get { return _isChecked; }

set {

SetCheckState(value, true, true);

}

}

private void SetCheckState(bool? value, bool updateChildren, bool up dateParent) {

if (_isChecked != value) {

_isChecked = value;

//通知选中项的集合

if (_isChecked == true) {

_checkedItems.Add(this);

PropertyChanged(this, new PropertyChangedEventArgs("Chec kedItems"));

} else if (_isChecked == false) {

_checkedItems.Remove(this);

PropertyChanged(this, new PropertyChangedEventArgs("Chec kedItems"));

}

PropertyChanged(this, new PropertyChangedEventArgs("IsChecke d"));

if (updateChildren) {

if (HasChildren()) {

Children.ForEach(c => c.SetCheckState(value, true, f alse));

}

}

if (updateParent && _parent != null) {

_parent.VerifyState();

}

}

}

private void VerifyState() {

bool? state = null;

for (int i = 0; i < this.Children.Count; ++i) {

bool? currentState = this.Children[i].IsChecked;

if (i == 0) {

state = currentState;

} else if (state != currentState) {

state = null;

break;

}

}

this.SetCheckState(state, false, true);

}

private bool _isExpanded;

public bool IsExpanded {

get { return _isExpanded; }

set {

if (value != _isExpanded) {

_isExpanded = value;

PropertyChanged(this, new PropertyChangedEventArgs("IsEx panded"));

}

if (!HasChildren()) {

Children.Remove(_temp);

LoadChildren();

}

}

}

private object _current;

public object Current {

get { return _current; }

set { _current = value; }

}

public string DisplayText {

get { return ((DepartmentTreeView.DB.SampleDataSet.DepartmentRow )Current)["DName"].ToString(); }

}

private DepartmentViewModel _parent;

public DepartmentViewModel Parent {

get { return _parent; }

set { _parent = value; }

}

private List _children;

public List Children {

get { return _children; }

private set { _children = value; }

}

#endregion

public static List Create() {

var list = DepartmentHelper.GetSubDepartments(0);

DepartmentViewModel root = new DepartmentViewModel(null);

_rootItem = root;

root.Children.Clear();

foreach (var item in list) {

root.Children.Add(new DepartmentViewModel(item));

}

return root.Children;

}

private DepartmentViewModel(object currentObject) {

Current = currentObject;

_isChecked = false;

Children = new List();

Children.Add(_temp);

}

///

/// 初始化,用于设置父节点

///

private void Init() {

if (!HasChildren()) return;

foreach (DepartmentViewModel child in Children) {

child.Parent = this;

child.Init();

}

PropertyChanged(this, new PropertyChangedEventArgs("Children")); }

///

/// 加载子节点

///

private void LoadChildren() {

if (Current != null) {

int pid = Convert.ToInt32(((DepartmentTreeView.DB.SampleData Set.DepartmentRow)Current)["DID"]);

var list = DepartmentHelper.GetSubDepartments(pid);

foreach (var item in list) {

DepartmentViewModel model = new DepartmentViewModel(item ) { _isChecked = this.IsChecked };

if (model.IsChecked == true) {

_checkedItems.Add(model);

PropertyChanged(this, new PropertyChangedEventArgs(" CheckedItems"));

}

Children.Add(model);

}

Init();

}

}

///

/// 判断是否有子节点(逻辑是:如果只有一个临时子节点,说明没有真正的子节点)

///

///

private bool HasChildren() {

return !(Children.Count == 1 && Children[0] == _temp);

}

public ObservableCollection CheckedItems { get {

return _checkedItems;

}

}

public event PropertyChangedEventHandler PropertyChanged;

}

}

5)创建WPF窗体

xmlns="https://www.doczj.com/doc/7d2704850.html,/winfx/2006/xaml/presentation"

xmlns:x="https://www.doczj.com/doc/7d2704850.html,/winfx/2006/xaml"

xmlns:local="clr-namespace:DepartmentTreeView"

Title="MainWindow" Height="329" Width="212" FontFamily="Arial">

当前选中项:

相关文档 最新文档