实际开发中控件的数据源肯定是动态绑定的,不可能在xaml里写死item项。既然要绑定,就先来几个实体类:
上面是类图,各类的代码如下:
BusinessBaseObject
代码语言:javascript复制using System.ComponentModel;
namespace BusinessObject
{
public class BusinessBaseObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// 属性改变时触发事件
/// </summary>
/// <param name="propertyName">Property that changed.</param>
protected void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (null != handler)
{
handler.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
SelectedItemBase
代码语言:javascript复制using System.Collections.ObjectModel;
using System.Windows.Markup;
namespace BusinessObject
{
[ContentProperty("Children")]//指示Children属性是 XAML 的Content内容属性
public class SelectedItemBase:BusinessBaseObject
{
public SelectedItemBase()
{
Children = new Collection<SelectedItemBase>();
IsSelected = true;
}
/// <summary>
/// 得到下级元素容器
/// </summary>
public Collection<SelectedItemBase> Children { get; private set; }
/// <summary>
/// 是否有子项
/// </summary>
public bool HasChild
{
get
{
return Children.Count > 0;
}
}
/// <summary>
/// 是否选中
/// </summary>
private bool? _isSelected;
/// <summary>
/// 是否被选中
/// </summary>
public bool? IsSelected
{
get
{
return _isSelected;
}
set
{
if (value != _isSelected)
{
_isSelected = value;
OnPropertyChanged("IsSelected");
}
}
}
}
}
NodeItem 主要用于treeview中的节点数据展示
代码语言:javascript复制using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Markup;
namespace BusinessObject
{
/// <summary>
/// 地区数据项
/// </summary>
public class NodeItem : SelectedItemBase
{
/// <summary>
/// 构造函数
/// </summary>
public NodeItem()
{
Text = "";
Value = "";
Description = "";
ImageUri = "/Common.Silverlight.Resource;component/img/Book.png";
}
/// <summary>
/// 节点文本
/// </summary>
public string Text { get; set; }
/// <summary>
/// 节点值
/// </summary>
public string Value { set; get; }
/// <summary>
/// 节点描述
/// </summary>
public string Description { get; set; }
/// <summary>
/// 节点图象
/// </summary>
public string ImageUri { get; set; }
}
}
MenuItem 主要用于菜单项展示
代码语言:javascript复制namespace BusinessObject
{
public class MenuItem:NodeItem
{
public MenuItem()
{
NavigateUri = "";
ImageUri = "/Common.Silverlight.Resource;component/img/Book_Open.png";
}
/// <summary>
/// 菜单点击后的链接地址
/// </summary>
public string NavigateUri { set; get; }
}
}
SampleData生成示例数据集合
代码语言:javascript复制using System.Collections.ObjectModel;
namespace BusinessObject
{
public class SampleData
{
private static ObservableCollection<NodeItem> _samplePlaceItemCollection;
private static ObservableCollection<MenuItem> _sampleMenuItemCollection;
public SampleData() { }
static SampleData()
{
#region 地区演示数据
_samplePlaceItemCollection = new ObservableCollection<NodeItem>();
NodeItem ShangHai = new NodeItem() { Text = "上海市", IsSelected = false, ImageUri = "/Common.Silverlight.Resource;component/img/Home.png" };
ShangHai.Children.Add(new NodeItem() { Text = "黄浦区", IsSelected = false });
ShangHai.Children.Add(new NodeItem() { Text = "闵行区", IsSelected = false });
ShangHai.Children.Add(new NodeItem() { Text = "徐汇区", IsSelected = false });
NodeItem HuBei = new NodeItem() { Text = "湖北省", IsSelected = null, ImageUri = "/Common.Silverlight.Resource;component/img/Book_Open.png" };
NodeItem WuHan = new NodeItem() { Text = "武汉市", ImageUri = "/Common.Silverlight.Resource;component/img/MSN.png" };
WuHan.Children.Add(new NodeItem() { Text = "汉口区" });
WuHan.Children.Add(new NodeItem() { Text = "汉阳区" });
WuHan.Children.Add(new NodeItem() { Text = "武昌区", IsSelected = false, ImageUri = "/Common.Silverlight.Resource;component/img/Computer.png" });
HuBei.Children.Add(WuHan);
HuBei.Children.Add(new NodeItem() { Text = "孝感市" });
_samplePlaceItemCollection.Add(ShangHai);
_samplePlaceItemCollection.Add(HuBei);
#endregion
#region
_sampleMenuItemCollection = new ObservableCollection<MenuItem>();
MenuItem itemBasic = new MenuItem() { Text = "基础数据", IsSelected = true, ImageUri = "/Common.Silverlight.Resource;component/img/Computer.png" };
itemBasic.Children.Add(new MenuItem() { Text = "部门管理", NavigateUri="Basic/Department.xap" });
itemBasic.Children.Add(new MenuItem() { Text = "员工管理", NavigateUri="Basic/Employee.xap" });
itemBasic.Children.Add(new MenuItem() { Text = "menu001", NavigateUri = "Plan/FFM.xap", ImageUri = "/Common.Silverlight.Resource;component/img/Book.png" });
itemBasic.Children.Add(new MenuItem() { Text = "menu002", NavigateUri = "Plan/FFM.xap" });
itemBasic.Children.Add(new MenuItem() { Text = "menu003", NavigateUri = "Plan/FFM.xap", ImageUri = "/Common.Silverlight.Resource;component/img/Book.png" });
itemBasic.Children.Add(new MenuItem() { Text = "menu004", NavigateUri = "Plan/FFM.xap" });
itemBasic.Children.Add(new MenuItem() { Text = "menu005", NavigateUri = "Plan/FFM.xap", ImageUri = "/Common.Silverlight.Resource;component/img/Book.png" });
itemBasic.Children.Add(new MenuItem() { Text = "menu006", NavigateUri = "Plan/FFM.xap" });
itemBasic.Children.Add(new MenuItem() { Text = "menu007", NavigateUri = "Plan/FFM.xap", ImageUri = "/Common.Silverlight.Resource;component/img/Book.png" });
itemBasic.Children.Add(new MenuItem() { Text = "menu008", NavigateUri = "Plan/FFM.xap" });
MenuItem itemMsg = new MenuItem() { Text = "报文管理", IsSelected=false, ImageUri = "/Common.Silverlight.Resource;component/img/Home.png" };
itemMsg.Children.Add(new MenuItem() { Text = "FFM报文计划", NavigateUri = "Plan/FFM.xap", ImageUri = "/Common.Silverlight.Resource;component/img/Book.png" });
itemMsg.Children.Add(new MenuItem() { Text = "FSU报文计划", NavigateUri = "Plan/FFM.xap" });
itemMsg.Children.Add(new MenuItem() { Text = "menu001", NavigateUri = "Plan/FFM.xap", ImageUri = "/Common.Silverlight.Resource;component/img/Book.png" });
itemMsg.Children.Add(new MenuItem() { Text = "menu002", NavigateUri = "Plan/FFM.xap" });
itemMsg.Children.Add(new MenuItem() { Text = "menu003", NavigateUri = "Plan/FFM.xap", ImageUri = "/Common.Silverlight.Resource;component/img/Book.png" });
itemMsg.Children.Add(new MenuItem() { Text = "menu004", NavigateUri = "Plan/FFM.xap" });
itemMsg.Children.Add(new MenuItem() { Text = "menu005", NavigateUri = "Plan/FFM.xap", ImageUri = "/Common.Silverlight.Resource;component/img/Book.png" });
itemMsg.Children.Add(new MenuItem() { Text = "menu006", NavigateUri = "Plan/FFM.xap" });
itemMsg.Children.Add(new MenuItem() { Text = "menu007", NavigateUri = "Plan/FFM.xap", ImageUri = "/Common.Silverlight.Resource;component/img/Book.png" });
itemMsg.Children.Add(new MenuItem() { Text = "menu008", NavigateUri = "Plan/FFM.xap" });
MenuItem itemOther = new MenuItem() { Text = "系统管理", IsSelected=false, ImageUri = "/Common.Silverlight.Resource;component/img/MSN.png" };
itemOther.Children.Add(new MenuItem() { Text = "系统日志", NavigateUri = "Event/FFM.xap" });
itemOther.Children.Add(new MenuItem() { Text = "退出登录", NavigateUri = "Plan/MSN.xap", ImageUri = "/Common.Silverlight.Resource;component/img/Book.png" });
itemOther.Children.Add(new MenuItem() { Text = "menu001", NavigateUri = "Plan/FFM.xap", ImageUri = "/Common.Silverlight.Resource;component/img/Book.png" });
itemOther.Children.Add(new MenuItem() { Text = "menu002", NavigateUri = "Plan/FFM.xap" });
itemOther.Children.Add(new MenuItem() { Text = "menu003", NavigateUri = "Plan/FFM.xap", ImageUri = "/Common.Silverlight.Resource;component/img/Book.png" });
itemOther.Children.Add(new MenuItem() { Text = "menu004", NavigateUri = "Plan/FFM.xap" });
itemOther.Children.Add(new MenuItem() { Text = "menu005", NavigateUri = "Plan/FFM.xap", ImageUri = "/Common.Silverlight.Resource;component/img/Book.png" });
itemOther.Children.Add(new MenuItem() { Text = "menu006", NavigateUri = "Plan/FFM.xap" });
itemOther.Children.Add(new MenuItem() { Text = "menu007", NavigateUri = "Plan/FFM.xap", ImageUri = "/Common.Silverlight.Resource;component/img/Book.png" });
itemOther.Children.Add(new MenuItem() { Text = "menu008", NavigateUri = "Plan/FFM.xap" });
_sampleMenuItemCollection.Add(itemBasic);
_sampleMenuItemCollection.Add(itemMsg);
_sampleMenuItemCollection.Add(itemOther);
#endregion
}
public static ObservableCollection<NodeItem> SamplePlaceItemCollection
{
get { return _samplePlaceItemCollection; }
}
public static ObservableCollection<MenuItem> SampleMenuItemCollection
{
get { return _sampleMenuItemCollection; }
}
}
}
TreeView、ContextMenu
为了将NoteItem中的IsSelected属性在绑定时自动转换成CheckBox的CheckState,需要写一个转换器
代码语言:javascript复制using System;
using System.Windows.Automation;
using System.Windows.Data;
namespace Common.Silverlight
{
public class BooleanToCheckStateConvertor : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
bool? isSelected = (bool?)value;
ToggleState result = ToggleState.Off;
if (isSelected.HasValue == false)
{
result = ToggleState.Indeterminate;
}
else if (isSelected.Value)
{
result = ToggleState.On;
}
return result;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
ToggleState state = (ToggleState)value;
bool? result = null;
switch (state)
{
case ToggleState.Indeterminate:
result = null;
break;
case ToggleState.Off:
result = false;
break;
case ToggleState.On:
result = true;
break;
default:
break;
}
return result;
}
}
}
然后需要定义数据模板,如果需要右键弹出菜单,也一并加在里面
代码语言:javascript复制<UserControl x:Class="Telerik.Sample.TreeView"
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"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400"
xmlns:model="clr-namespace:BusinessObject;assembly=BusinessObject"
xmlns:common="clr-namespace:Common.Silverlight;assembly=Common.Silverlight"
xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation">
<Grid x:Name="LayoutRoot" Background="White">
<Grid.Resources>
<telerik:ContainerBindingCollection x:Name="BindingsCollection">
<!--用于将节点的选中状态,与数据项的IsSelected绑定-->
<telerik:ContainerBinding PropertyName="CheckState" Binding="{Binding IsSelected,Converter={StaticResource BooleanToCheckStateConvertor}, Mode=TwoWay}" />
<!--将节点图象与数据项的ImageUri绑定-->
<telerik:ContainerBinding PropertyName="DefaultImageSrc" Binding="{Binding ImageUri}" />
</telerik:ContainerBindingCollection>
<!--数据节点模板-->
<DataTemplate x:Key="NodeTemplate" telerik:ContainerBinding.ContainerBindings="{StaticResource BindingsCollection}">
<TextBlock Text="{Binding Text}" />
</DataTemplate>
<!--子节点模板-->
<telerik:HierarchicalDataTemplate x:Key="ChildTemplate" ItemTemplate="{StaticResource NodeTemplate}"
ItemsSource="{Binding Children}" telerik:ContainerBinding.ContainerBindings="{StaticResource BindingsCollection}">
<TextBlock Text="{Binding Text}" />
</telerik:HierarchicalDataTemplate>
<!--父节点模板-->
<telerik:HierarchicalDataTemplate x:Key="ParentTemplate" ItemTemplate="{StaticResource ChildTemplate}"
ItemsSource="{Binding Children}" telerik:ContainerBinding.ContainerBindings="{StaticResource BindingsCollection}">
<TextBlock Text="{Binding Text}" />
</telerik:HierarchicalDataTemplate>
</Grid.Resources>
<telerik:RadTreeView
ItemsSource="{Binding Source={StaticResource SampleDataSource}, Path=SamplePlaceItemCollection}"
ItemTemplate="{StaticResource ParentTemplate}" SelectionMode="Extended" IsLineEnabled="True" ItemsOptionListType="CheckList" IsOptionElementsEnabled="True" IsRootLinesEnabled="True" IsTriStateMode="True" Margin="10">
<telerik:RadTreeView.ItemContainerStyle>
<Style TargetType="telerik:RadTreeViewItem">
<!--默认全展开-->
<Setter Property="IsExpanded" Value="True"/>
</Style>
</telerik:RadTreeView.ItemContainerStyle>
<!--右键弹出菜单-->
<telerik:RadContextMenu.ContextMenu>
<telerik:RadContextMenu x:Name="ContextMenu1" ItemClick="ContextMenuClick"
Opened="ContextMenuOpened">
<telerik:RadMenuItem Header="添加" Tag="Add" />
<telerik:RadMenuItem Header="删除" Tag="Delete" />
<telerik:RadMenuItem Header="修改" Tag="Edit" />
<telerik:RadMenuItem IsSeparator="True" />
<telerik:RadMenuItem Header="设置菜单权限" Tag="MenuRight" />
<telerik:RadMenuItem Header="设置数据范围" Tag="DataRange" />
</telerik:RadContextMenu>
</telerik:RadContextMenu.ContextMenu>
</telerik:RadTreeView>
</Grid>
</UserControl>
这里面用到了几个资源,定义在全局App.Xaml里
代码语言:javascript复制<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="Telerik.App"
xmlns:model ="clr-namespace:BusinessObject;assembly=BusinessObject"
xmlns:common ="clr-namespace:Common.Silverlight;assembly=Common.Silverlight"
>
<Application.Resources>
<!--示例数据源-->
<model:SampleData x:Key="SampleDataSource"></model:SampleData>
<!--转换器:用于bool?转换成CheckBox的三种选中状态-->
<common:BooleanToCheckStateConvertor x:Key="BooleanToCheckStateConvertor"></common:BooleanToCheckStateConvertor>
</Application.Resources>
</Application>
右键弹出菜单点击后,我们需要知道是在哪个节点上弹出的,以及我们选择了哪个菜单项,需要一些后端处理代码
代码语言:javascript复制using System.Windows;
using System.Windows.Controls;
using BusinessObject;
using Telerik.Windows.Controls;
namespace Telerik.Sample
{
public partial class TreeView : UserControl
{
NodeItem selectedNodeItem = null;
public TreeView()
{
InitializeComponent();
this.Loaded = new RoutedEventHandler(MainPage_Loaded);
}
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
//this.RadTreeView1.ItemsSource = SampleData.SamplePlaceItemCollection;
}
/// <summary>
/// 菜单弹出后,点击具体菜单项时触发
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ContextMenuClick(object sender, Windows.RadRoutedEventArgs e)
{
var origin_src = e.OriginalSource as RadMenuItem;
//反馈操作结果
DialogParameters pars = new DialogParameters();
pars.Header = "信息";
pars.Content = string.Format("你选择的菜单是:n{0},{1}nn当前节点为:{2}n{3}", origin_src.Header.ToString(), origin_src.Tag.ToString(), selectedNodeItem.Text,selectedNodeItem.ImageUri);
RadWindow.Alert(pars);
selectedNodeItem = null;
}
/// <summary>
/// 菜单弹出时触发
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ContextMenuOpened(object sender, RoutedEventArgs e)
{
RadTreeViewItem item = this.ContextMenu1.GetClickedElement<RadTreeViewItem>();
if (item != null)
{
selectedNodeItem = item.DataContext as NodeItem;
}
}
}
}
运行效果图:
选择一个弹出菜单项后的效果:
PanelBar的Accordion效果
代码语言:javascript复制<UserControl x:Class="Telerik.Sample.Accordion"
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"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400"
xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation">
<Grid>
<Grid.Resources>
<telerik:ContainerBindingCollection x:Name="BindingsCollection">
<!--用于将工作间组的展开状态,与数据项的IsSelected绑定-->
<telerik:ContainerBinding PropertyName="IsExpanded" Binding="{Binding IsSelected, Mode=TwoWay}" />
</telerik:ContainerBindingCollection>
<!--菜单项模板-->
<telerik:HierarchicalDataTemplate x:Key="ChildTemplate">
<StackPanel>
<Image Source="{Binding ImageUri}" Width="48" Height="48"></Image>
<TextBlock Text="{Binding Text}" Margin="0,5,0,0" TextAlignment="Center"></TextBlock>
</StackPanel>
</telerik:HierarchicalDataTemplate>
<!--菜单组模板-->
<telerik:HierarchicalDataTemplate x:Key="ParentTemplate" ItemTemplate="{StaticResource ChildTemplate}" ItemsSource="{Binding Children}" telerik:ContainerBinding.ContainerBindings="{StaticResource BindingsCollection}">
<StackPanel Orientation="Horizontal">
<Image Source="{Binding ImageUri}" Width="24" Height="24" Margin="5,0,5,0"></Image>
<TextBlock Text="{Binding Text}" Margin="0,2,0,0" FontSize="14" FontWeight="Bold"></TextBlock>
</StackPanel>
</telerik:HierarchicalDataTemplate>
</Grid.Resources>
<telerik:RadPanelBar Background="White" Orientation="Vertical"
VerticalAlignment="Top" HorizontalAlignment="Left" ExpandMode="Single" Width="150" ItemTemplate="{StaticResource ParentTemplate}" ItemsSource="{Binding Source={StaticResource SampleDataSource}, Path=SampleMenuItemCollection}">
<!--<telerik:RadPanelBarItem IsExpanded="True" Header="基础数据" >
<StackPanel>
<telerik:RadButton Margin="0,3">
<StackPanel>
<Image Source="/Common.Silverlight.Resource;component/img/Book.png" Width="64" Height="64" ></Image>
<TextBlock TextAlignment="Center">部门管理</TextBlock>
</StackPanel>
</telerik:RadButton>
<telerik:RadButton Margin="0,3">
<StackPanel>
<Image Source="/Common.Silverlight.Resource;component/img/Book_Open.png" Width="64" Height="64" ></Image>
<TextBlock TextAlignment="Center" Text="adfasdfasdf"/>
</StackPanel>
</telerik:RadButton>
</StackPanel>
</telerik:RadPanelBarItem>
<telerik:RadPanelBarItem Header="报文管理">
<StackPanel>
<telerik:RadButton Content="FFM报文计划" />
<telerik:RadButton Content="FSU报文计划" />
</StackPanel>
</telerik:RadPanelBarItem>-->
</telerik:RadPanelBar>
</Grid>
</UserControl>
运行时截图:
TabPanel Frame
为了节省空间,将多个界面以Tab标签页方式整合在一起是常见的用法,每个标签页的内容通常是实例化一个单独的Xaml模块,可以考虑每个标签页的内容以Frame形式嵌入一个xaml
代码语言:javascript复制<UserControl
x:Class="Telerik.SampleIndex"
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"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400"
xmlns:local="clr-namespace:Telerik.Sample"
xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation">
<Grid >
<telerik:RadTabControl
DisplayMemberPath="Content" ScrollMode="Viewport"
BorderThickness="0">
<telerik:RadTabItem Header="测试Tab" IsSelected="True">
<telerik:RadTabItem.Content>
<telerik:RadTreeView IsLineEnabled="True" ItemsOptionListType="CheckList" IsOptionElementsEnabled="True">
<telerik:RadTreeViewItem Header="中国航信" IsExpanded="True" DefaultImageSrc="/Common.Silverlight.Resource;component/img/Book_Open.png" >
<telerik:RadTreeViewItem Header="天信达" DefaultImageSrc="/Common.Silverlight.Resource;component/img/Book.png">
</telerik:RadTreeViewItem>
</telerik:RadTreeViewItem>
</telerik:RadTreeView>
</telerik:RadTabItem.Content>
</telerik:RadTabItem>
<telerik:RadTabItem Header="TreeView">
<telerik:RadTabItem.Content>
<telerik:RadFrame HorizontalAlignment="Left" x:Name="radFrame1" VerticalAlignment="Top" >
<local:TreeView/>
</telerik:RadFrame>
</telerik:RadTabItem.Content>
</telerik:RadTabItem>
<telerik:RadTabItem Header="Accordion">
<telerik:RadTabItem.Content>
<telerik:RadFrame HorizontalAlignment="Left" x:Name="radFrame2" VerticalAlignment="Top" >
<local:Accordion/>
</telerik:RadFrame>
</telerik:RadTabItem.Content>
</telerik:RadTabItem>
</telerik:RadTabControl>
</Grid>
</UserControl>