XAML文件
<UserControl.Resources>
<local:CITypeOfStateIconVisiblityConverter x:Key="xCITypeOfStateIconVisiblityConverter" />
<local:ToolTipEmptyConverter x:Key="_ToolTipEmptyConverter" />
<Style x:Key="TreeViewItemStyle" TargetType="TreeViewItem">
<!--用了IsExpanded绑定,当改变节点对象的对应属性时,节点就会展开/合上-->
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
<!--用了IsSelected绑定,当改变节点对象的对应属性时,节点选中/取消全中,但前提是节点已经被Load到界面上-->
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
<Setter Property="KeyboardNavigation.AcceptsReturn" Value="True" />
</Style>
<HierarchicalDataTemplatex:Key="TreeViewItemTemplate" ItemsSource="{Binding Nodes}" >
<StackPanel Orientation="Horizontal">
<shared:PixelSnapper VerticalAlignment="Center" HorizontalRoundMode="Floor" VerticalRoundMode="Floor">
<StackPanel Orientation="Horizontal">
<bu:StateIcon Visibility="{Binding Converter={StaticResource xCITypeOfStateIconVisiblityConverter}}" Width="12" Height="12" AOrC="all" MonitorState="{Binding AllState}"></bu:StateIcon>
<Image ToolTip="{Binding IconUrl}" Width="16" Height="16" Source="{Binding IconUrl}" Margin="2"/>
</StackPanel>
</shared:PixelSnapper>
<StackPanel Margin="0" Orientation="Horizontal" ToolTip="{Binding PropertyOfTreeView.ToolTip, Converter={StaticResource _ToolTipEmptyConverter}}">
<TextBlock VerticalAlignment="Center" Margin="2" Text="{Binding Title}"></TextBlock>
<TextBlock VerticalAlignment="Center" Margin="2" Foreground="#0D43F6" Text="{Binding SubTitle}"></TextBlock>
</StackPanel>
</StackPanel>
</HierarchicalDataTemplate>
</UserControl.Resources>
<ScrollViewer HorizontalScrollBarVisibility="Hidden">
<TreeView x:FieldModifier="public" Name="xTreeView" BorderThickness="0"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="0"
Background="Transparent"
TreeViewItem.Expanded="_treeView_Expanded"
PreviewMouseRightButtonDown="xTreeViewRightButtonDown"
PreviewMouseLeftButtonDown="xTreeView_PreviewMouseLeftButtonDown"
ItemContainerStyle="{StaticResource TreeViewItemStyle}"
ItemTemplate="{StaticResource TreeViewItemTemplate}"
ItemsSource="{Binding Mode=OneTime}"/>
</ScrollViewer>
CS文件
//用于展开时,判断下级节点是否已经装载,如果装载,则直接展开,如果没有展开,则从数据库中读取
private void _treeView_Expanded(object sender, RoutedEventArgs e)
{
try
{
TreeViewItem item = e.OriginalSource as TreeViewItem;
SmartCINode p = item.DataContext as SmartCINode;
p.IsExpanded = item.IsExpanded;
//IsLoad是绑定的对象中的一个属性,用来记录下级节点是否装载
if (p.PropertyOfTreeView.IsLoaded)
{
return;
}
else
{
this.Cursor = Cursors.Wait;
BuildTreeViewNode(p);//从数据库中读取数据
this.Cursor = Cursors.Arrow;
}
}
catch (Exception ex)
{
MessageHelper.ShowException(ex);
}
}
//鼠标右键点击时,选中树节点
bool IsMouseRightButton = false;//
private void xTreeViewRightButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
TreeViewItem item = UIElementHelper.GetTemplatedAncestor<TreeViewItem>(e.OriginalSource as FrameworkElement);
if (item != null)
{
IsMouseRightButton = true;
//此时会触发TreeView的SelectedItemChanged事件,IsMouseRightButton用于在事件中判断是否是鼠标右键触发选中节点改变
item.IsSelected = true;
IsMouseRightButton = false;
}
}
//鼠标左键双击时,触发自定义事件TreeNodeDblClicked,并取消TreeView自带的双击展开/合上节点的动作
public event CmdbResourceTreeEventHandler TreeNodeDblClicked;
void xTreeView_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
IInputElement o = xTreeView.InputHitTest(e.GetPosition(this));
//path和border指的是节点前面的+号,image指的是节点前面的图片
//if (e.ClickCount > 1 && o.GetType().Name.ToLower() != "path" && o.GetType().Name.ToLower() != "border" && o.GetType().Name.ToLower() != "image")//双击本文,触发自定义的TreeNodeDblClicked事件,并且取消TreeView自带的双击展开/合上节点的动作,双击图片,不触发TreeNodeDblClicked,并且不取消TreeView自带的双击展开/合上节点的动作
if (e.ClickCount > 1)//双击图片或者文本,都能触发自定义的TreeNodeDblClicked事件,并且取消TreeView自带的双击展开/合上节点的动作
{
e.Handled = true;//取消TreeView自带的双击展开/合上节点的动作
if (xTreeView.SelectedItem == null)
return;
//触发自定义事件TreeNodeDblClicked
if (TreeNodeDblClicked != null)
{
SmartCINode node = xTreeView.SelectedItem as SmartCINode;
CmdbResourceTreeEventArgs args = new CmdbResourceTreeEventArgs();
args.CurrentNode = node;
TreeNodeDblClicked(this, args);
}
}
}
树节点绑定的对象
[Serializable]
public class SmartCINode : INotifyPropertyChanged
{
public SmartCINode()
{
Nodes = new ObservableCollection<SmartCINode>();
PropertyOfTreeView = new SmartTreePropertyHelper();
PropertyOfDiagram = new SmartDiagramPropertyHelper(this);
IsVirtualNode = false;
}
[field: NonSerializedAttribute()]
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
[field: NonSerializedAttribute()]
DrawingBrush _IconBrush = null;
public DrawingBrush IconBrush
{
get { return _IconBrush; }
set
{
if (value != this._IconBrush)
{
this._IconBrush = value;
NotifyPropertyChanged("IconBrush");
}
}
}
public bool IsVirtualNode { get; set; }
public CITypeOfCmdb CIType { get; set; }
public string Key { get; set; }
public string IconUrl { get; set; }
public string Title
{
get { return _Title; }
set
{
if (value != this._Title)
{
this._Title = value;
NotifyPropertyChanged("Title");
}
}
}string _Title = string.Empty;
public string SubTitle
{
get { return _SubTitle; }
set
{
if (value != this._SubTitle)
{
this._SubTitle = value;
NotifyPropertyChanged("SubTitle");
}
}
}string _SubTitle = string.Empty;
public int AvaState
{
get { return _AvaState; }
set
{
if (value != this._AvaState)
{
this._AvaState = value;
NotifyPropertyChanged("AvaState");
}
}
}int _AvaState = -1;
public int CapState
{
get { return _CapState; }
set
{
if (value != this._CapState)
{
this._CapState = value;
NotifyPropertyChanged("CapState");
}
}
}int _CapState = -1;
public int AllState
{
get
{
return _AllState;
}
set
{
if (value != this._AllState)
{
this._AllState = value;
NotifyPropertyChanged("AllState");
}
}
}int _AllState = 1;
public bool IsVisible { get; set; }
[field: NonSerializedAttribute()]
SolidColorBrush _StateColorBrush = Brushes.Transparent;
public SolidColorBrush StateColorBrush
{
get
{
return _StateColorBrush;
}
set
{
if (value != this._StateColorBrush)
{
this._StateColorBrush = value;
NotifyPropertyChanged("StateColorBrush");
}
}
}
public bool IsShowErrorAnnimation
{
get
{
return _IsShowErrorAnnimation;
}
set
{
if (value != this._IsShowErrorAnnimation)
{
this._IsShowErrorAnnimation = value;
NotifyPropertyChanged("IsShowErrorAnnimation");
}
}
}bool _IsShowErrorAnnimation = false;
public bool IsHasError
{
get
{
return _IsHasError;
}
set
{
if (value != this._IsHasError)
{
this._IsHasError = value;
NotifyPropertyChanged("IsHasError");
}
}
}bool _IsHasError = false;
public bool IsShowErrorSharpIsRectange
{
get
{
return _IsShowErrorShapIsRectang;
}
set
{
if (value != this._IsShowErrorShapIsRectang)
{
this._IsShowErrorShapIsRectang = value;
NotifyPropertyChanged("IsShowErrorSharpIsRectange");
}
}
}bool _IsShowErrorShapIsRectang = false;
public CLRDataObjectBase DataObject { get; set; }
public object ParamOne { get; set; }
public object ParamTwo { get; set; }
public object ParamThree { get; set; }
public ObservableCollection<SmartCINode> Nodes { get; set; }
public SmartTreePropertyHelper PropertyOfTreeView { get; set; }
public SmartDiagramPropertyHelper PropertyOfDiagram { get; set; }
private SmartCINode _parentNode = null;
public SmartCINode ParentNode
{
get
{
return _parentNode;
}
set
{
_parentNode = value;
if (_parentNode != null)
{
this.PropertyOfTreeView.Level = _parentNode.PropertyOfTreeView.Level + 1;
}
}
}
private bool _isExpanded = false;
/// <summary>
/// 节点是否展开
/// </summary>
public bool IsExpanded
{
get { return _isExpanded; }
set
{
_isExpanded = value;
NotifyPropertyChanged("IsExpanded");
}
}
private bool _IsSelected = false;
/// <summary>
/// 节点是否选中
/// </summary>
public bool IsSelected
{
get { return _IsSelected; }
set
{
_IsSelected = value;
NotifyPropertyChanged("IsSelected");
}
}
}
Build树节点的CS文件
[Serializable]
public class CmdbResourceTreeViewAction : BaseAction
{
[NonSerialized]
DBFactory con = null;
public SmartCINode ParentNode { get; set; }
public override void Excute()
{
con = DBFactory.CreateConnection();
if (ParentNode.Key == "Root")
LoadFirstLevelNode();
else
{
CITypeOfCmdb xCurrentType = EnumHelper.GetEnumObject<CITypeOfCmdb>(ParentNode.CIType);
switch (xCurrentType)
{
case CITypeOfCmdb.OrganizationRoot:
case CITypeOfCmdb.Organization:
case CITypeOfCmdb.OrganizationGroup:
MakeOrganization(ParentNode.Key == "CITypeOfCmdb.OrganizationRoot");
break;
}
}
con.Close();
}
public string RootNodeFilter { get; set; }
// 装载整个CMDB的根节点
private void LoadFirstLevelNode()
{
ParentNode = new SmartCINode();
SmartCINode node = null;
if (RootNodeFilter == null || RootNodeFilter.IndexOf("Organization") != -1)
{
node = new SmartCINode();
node.Key = "CITypeOfCmdb.OrganizationRoot";
node.CIType = CITypeOfCmdb.OrganizationRoot;
node.Title = LanguageManager.Find(CITypeOfCmdb.Organization.ToString());
node.PropertyOfTreeView.NodeSubCount = Convert.ToInt32(con.ExecuteScalar("SELECT COUNT(0) FROM C_ORGAN"));
node.PropertyOfTreeView.IsRoot = true;
ParentNode.Nodes.Add(node);
}
}
// 机构
private void MakeOrganization(bool IsRoot)
{
string sql = "SELECT (select count(0) from C_ORGAN A where A.AF_PID=B.P_GUID) as SUBCOUNT, A_ISTYPE,P_GUID,D_TEXT FROM C_ORGAN B where AF_PID='{0}' ORDER BY A_IsType, A_SORT";
if (IsRoot)
sql = String.Format(sql, "root");
else
sql = String.Format(sql, ParentNode.Key);
IDataReader reader = con.ExecuteReader(sql);
while (reader.Read())
{
SmartCINode node = new SmartCINode();
node.Title = reader["D_TEXT"].ToString();
node.PropertyOfTreeView.NodeSubCount = Convert.ToInt32(reader["SUBCOUNT"]);
node.Key = reader["P_GUID"].ToString();
node.CIType = (Convert.ToBoolean(reader["A_ISTYPE"]) ? CITypeOfCmdb.OrganizationGroup : CITypeOfCmdb.Organization);
if(node.CIType == CITypeOfCmdb.Organization)
node.PropertyOfTreeView.IsDetail = true;
ParentNode.Nodes.Add(node);
}
reader.Close();
}
}