在实际应用中,我们常常会遇到创建菜单树的情况,而Silverlight的TreeView有时候不能满足要求,在这里我们将使用Accordion模拟一个效果比较好的菜单。

        在本节中,我们使用绑定的方式来动态的显示ObservableCollection数据源集合。

        首先我们需要在项目中引入System.Windows.Controls.Toolkit.dll和 System.Windows.Controls.Layout.Toolkit.dll两个DLL文件。然后再XAML和XAML.CS代码中引用他 们。

        然后我们开始准备数据源部分,首先我们声明两个实体类,Catalog类和TestSimple类。其中Catalog类有一个属性为 TestSimple类的集合(通俗的说就是Catalog类的一个属性是多个TestSimple类对象的实体)。Catalog类是一级菜 单,TestSimple类是二级菜单,所以一级菜单除了自己需要名字之外,还需要有多个二级菜单项。在这里,我们贴出数据源的两个实体类代码如下:

 

  1. /// <summary> 
  2.   /// 一级菜单 
  3.   /// </summary> 
  4.   public class Catalog 
  5.   { 
  6.       public Catalog()//实例化本类的时候,调用本构造函数让初始化TestSimples属性 
  7.       { 
  8.           TestSimples = new ObservableCollection<TestSimple>(); 
  9.       } 
  10.  
  11.       public string CatalogName { get; set; } //一级菜单名称 
  12.       public ObservableCollection<TestSimple> TestSimples { get; set; }//二级菜单项的集合。 
  13.   } 
  14.   /// <summary> 
  15.   /// 二级菜单项 
  16.   /// </summary> 
  17.   public class TestSimple 
  18.   { 
  19.       public string Name { get; set; } //二级菜单名称 
  20.       public string TestID { get; set; } //二级菜单ID 
  21.   } 

        声明了这两个实体类之后,我们需要构造数据源集合,然后绑定到Accordion菜单,其关键代码如下:

 

  1. ObservableCollection<Catalog> catalogsk = new ObservableCollection<Catalog>(); 
  2. string BlackStr = " "
  3. catalogsk.Add
  4. new Catalog() 
  5. CatalogName = "配置菜单"
  6. TestSimples = new ObservableCollection<TestSimple>() 
  7. new TestSimple(){Name=BlackStr+"系统配置",TestID="configSystem"}, 
  8. new TestSimple(){Name=BlackStr+"用户配置",TestID="configUser"}, 
  9. new TestSimple(){Name=BlackStr+"日志配置",TestID="configCatalog"}, 
  10. new TestSimple(){Name=BlackStr+"网络配置",TestID="configNetwork"}, 
  11. ); 
  12. catalogsk.Add
  13. new Catalog() 
  14. CatalogName = "查询菜单"
  15. TestSimples = new ObservableCollection<TestSimple>() 
  16. new TestSimple(){Name=BlackStr+"查询成绩",TestID="SearchSystem"}, 
  17. new TestSimple(){Name=BlackStr+"查询日志",TestID="SearchUser"}, 
  18. new TestSimple(){Name=BlackStr+"查询新闻",TestID="SearchNews"}, 
  19. new TestSimple(){Name=BlackStr+"查询数目",TestID="SearchNumber"}, 
  20. new TestSimple(){Name=BlackStr+"查询地理",TestID="SearchAddr"}, 
  21. new TestSimple(){Name=BlackStr+"查询书籍",TestID="SearchProgram"}, 
  22. ); 
  23. catalogsk.Add
  24. new Catalog() 
  25. CatalogName = "修改菜单"
  26. TestSimples = new ObservableCollection<TestSimple>() 
  27. new TestSimple(){Name=BlackStr+"查询成绩",TestID="EditSystem"}, 
  28. new TestSimple(){Name=BlackStr+"修改日志",TestID="EditUser"}, 
  29. new TestSimple(){Name=BlackStr+"修改新闻",TestID="EditNews"}, 
  30. new TestSimple(){Name=BlackStr+"修改数目",TestID="EditNumber"}, 
  31. new TestSimple(){Name=BlackStr+"修改地理",TestID="EditAddr"}, 
  32. new TestSimple(){Name=BlackStr+"修改书籍",TestID="EditProgram"}, 
  33. ); 
  34. theList.ItemsSource = catalogsk; 

我们再贴出XAML关键代码即可。在这里

 

  1. <layoutToolkit:Accordion x:Name="theList" SelectionMode="ZeroOrMore" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Top" Width="200" Margin="5" BorderBrush="#FF849AAD" Height="Auto" BorderThickness="1"
  2. <layoutToolkit:Accordion.ItemTemplate> 
  3. <DataTemplate> 
  4. <StackPanel> 
  5. <TextBlock Text="{Binding Name}" /> 
  6. </StackPanel> 
  7. </DataTemplate> 
  8. </layoutToolkit:Accordion.ItemTemplate> 
  9. <layoutToolkit:Accordion.ContentTemplate> 
  10. <DataTemplate> 
  11. <ListBox ItemsSource="{Binding TestSimples}" BorderThickness="0" Width="200" HorizontalAlignment="Stretch"
  12. <ListBox.ItemTemplate> 
  13. <DataTemplate> 
  14. <TextBlock Text="{Binding Name}" Tag="{Binding TestID}" MouseLeftButtonDown="TextBlock_MouseLeftButtonDown"/> 
  15. </DataTemplate> 
  16. </ListBox.ItemTemplate> 
  17. </ListBox> 
  18. </DataTemplate> 
  19. </layoutToolkit:Accordion.ContentTemplate> 
  20. </layoutToolkit:Accordion> 

        其中SelectionMode="ZeroOrMore"是设置本菜单的可以打开0个一级菜单也可以同时打开多个菜单项。 Accordion.ItemTemplate是一级菜单的绑定列,Accordion.ContentTemplate是二级菜单的绑定列,在这里,二 级菜单里面我们再内嵌了一个ListBox,然后这个ListBox再绑定了一个TextBlock列,并且这个列还有一个鼠标点击事件,在这个事件里面 弹出触发事件的TextBlock的Tag标签值。通过这个标签值,我们可以控制点击菜单某项之后显示什么页面。

        至此,我们使用Accordion控件模拟了一个菜单,并且可以根据数据源自动生成菜单项。在这里我们贴出完整的源代码如下:

MainPage.xaml.cs
<UserControl x:Class="SLReadXML.MainPage"
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"
xmlns:layoutToolkit
="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Layout.Toolkit"
mc:Ignorable
="d"
d:DesignHeight
="300" d:DesignWidth="400">

<Grid x:Name="LayoutRoot" Background="White">
<layoutToolkit:Accordion x:Name="theList" SelectionMode="ZeroOrMore" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Top" Width="200" Margin="5" BorderBrush="#FF849AAD" Height="Auto" BorderThickness="1">
<layoutToolkit:Accordion.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding CatalogName}" />
</StackPanel>
</DataTemplate>
</layoutToolkit:Accordion.ItemTemplate>
<layoutToolkit:Accordion.ContentTemplate>
<DataTemplate>
<ListBox ItemsSource="{Binding TestSimples}" BorderThickness="0" Width="200" HorizontalAlignment="Stretch">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" Tag="{Binding TestID}" MouseLeftButtonDown="TextBlock_MouseLeftButtonDown"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</DataTemplate>
</layoutToolkit:Accordion.ContentTemplate>
</layoutToolkit:Accordion>
</Grid>
</UserControl>