您的位置:首页 > 其它

WPF-菜单和Tab控件

2015-07-24 17:16 633 查看

WPF-菜单和Tab控件

  因为菜单和Tab控件一起用,所以就拿出来一块写

Tab控件

  定义一个名为ViewItem类,定义Tab的属性

/// <summary>
/// tab  item
/// </summary>
public class ViewItem
{
/// <summary>
/// 标题
/// </summary>
public string Header
{
get;
set;
}

/// <summary>
/// 主键名称
/// </summary>
public string KeyName
{
get;
set;
}

/// <summary>
/// the show Control
/// </summary>
public object ViewControl
{
get;
set;
}
}


  TabControl用的是Dev的控件,所以先要引用三个Dev的DLL,分别是DevExpress.Xpf.Core,DevExpress,Xpf.Docking,DevExpress.Xpf.Layout.Core。

  新建一个UserControl,命名为MenuControl,在主窗体的Window中需要添加一下引用

xmlns:dxd="http://schemas.devexpress.com/winfx/2008/xaml/docking"         xmlns:c="clr-namespace:RemindWin"
xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
Name="MainView_View"


  其中,c引用的是MenuControl所在的文件夹,因为要用到MenuControl,所以需要引用MenuControl所在的文件夹。并为窗体命名为“MainView_View”(后面用到)。

  定义一个DockPanel,在其的顶端设置菜单栏,内容放TabControl,也可以在下面放FootBar,这里省略,主窗体代码如下:

<Grid x:Name="MainView">
<DockPanel LastChildFill="True">
<c:MenuControl DockPanel.Dock="Top" HorizontalAlignment="Left"/>
<dxd:DockLayoutManager x:Name="dockManager" UseLayoutRounding="True" AllowCustomization="False">
<dxd:LayoutGroup Orientation="Vertical" >
<dxd:DocumentGroup Name="documentContainer"
SelectedTabIndex="{Binding SelectedTabIndex,Mode=TwoWay}"
ItemsSource="{Binding ItemList}"
DestroyOnClosingChildren="False"
Background="Azure"
ClosePageButtonShowMode="InActiveTabPageAndTabControlHeader">
<dxd:DocumentGroup.ItemStyle>
<Style TargetType="dxd:DocumentPanel">
<Setter Property="CloseCommand" Value="{Binding DataContext.CloseCommand,ElementName=MainView}" />
<Setter Property="Caption" Value="{Binding Header}"></Setter>
<Setter Property="AllowFloat" Value="False"></Setter>
<Setter Property="AllowMaximize" Value="False"></Setter>
</Style>
</dxd:DocumentGroup.ItemStyle>
<dxd:DocumentGroup.ItemContentTemplate>
<DataTemplate>
<ContentControl Content="{Binding ViewControl}"></ContentControl>
</DataTemplate>
</dxd:DocumentGroup.ItemContentTemplate>
</dxd:DocumentGroup>
</dxd:LayoutGroup>
</dxd:DockLayoutManager>
</DockPanel>
</Grid>


  binding了Model中的ItemList,这是Tab集合,SelectedTabIndex是所选Tab的索引,为Int型,每个Tab有一个Close事件,Binding后台代码中的CloseCommand事件,属性Caption,banding了ViewItem中的Header,每个Tab的内容ContentControl绑定了ViewItem中的ViewControl,其中需要注意Grid的Name与<Setter>里面的元素一致。

  添加主窗体的ViewModel,命名MainViewModel,定义ItemList和SelectedTabIndex(引用了SimpleMvvmToolkit)

<UserControl.Resources>
<HierarchicalDataTemplate x:Key="ItemTemplate"
ItemsSource="{Binding Childrens}">
<StackPanel Orientation="Horizontal"  VerticalAlignment="Center">
<TextBlock Text="{Binding Header}"
IsEnabled="{Binding IsEnabled}"  VerticalAlignment="Center"/>
</StackPanel>
</HierarchicalDataTemplate>
<ControlTemplate x:Key="MenuSeparatorTemplate">
<Separator />
</ControlTemplate>
</UserControl.Resources>

<Menu DockPanel.Dock="Top"
VerticalAlignment="Top"
ItemsSource="{Binding MenuList}"
ItemTemplate="{StaticResource ItemTemplate}">

<!-- 菜单背景色-->
<Menu.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1.5">
<GradientStop Color="#f2f2f2" Offset="0.5"/>
<GradientStop Color="#F8F9FB" Offset="01"/>
</LinearGradientBrush>
</Menu.Background>
<Menu.ItemContainerStyle>
<Style TargetType="MenuItem">
<Setter Property="IsEnabled"
Value="{Binding IsEnabled}" />
<Setter Property="Command"
Value="{Binding SelectedCommand}" />
<Setter Property="CommandParameter"
Value="{Binding Header}" />
<Setter Property="FontSize" Value="14"/>

<Style.Triggers>
<DataTrigger Binding="{Binding }"
Value="{x:Null}">
<Setter Property="Template"
Value="{StaticResource MenuSeparatorTemplate}" />
</DataTrigger>
</Style.Triggers>

</Style>
</Menu.ItemContainerStyle>
</Menu>


View Code
  定义菜单的ViewModel,名为MenuControlModel,定义属性

#region Properties

private List<MenuItem> m_MainMenus = new List<MenuItem>();
public List<MenuItem> MenuList
{
get
{
return m_MainMenus;
}
set
{
m_MainMenus = value;
NotifyPropertyChanged(x => x.MenuList);
}
}

#endregion


  定义递归设置所有菜单的命令

/// <summary>
/// 递归设置所有菜单的命令
/// </summary>
/// <param name="Menus"></param>
void SetMenuCommand(List<MenuItem> Menus)
{
foreach (var item in Menus)
{
item.SelectedCommand = new DelegateCommand<string>(OpenMenu);
if (item.Childrens.Count > 0) SetMenuCommand(item.Childrens);
}
}


  定义点击菜单Item时执行的方法,其中第一个判断是找到主窗体,再进行操作,如果菜单的Name中包含“测试”两个字符,则使用第一个添加Tab的方法,否则,用第二种。Control_Test和TestModel分别是UserControl和其ViewModel。

/// <summary>
/// 打开方法
/// </summary>
/// <param name="MenuName"></param>
private void OpenMenu(string MenuName)
{
foreach (System.Windows.Window win in System.Windows.Application.Current.Windows)
{
if (win.Name == "MainView_View")
{
if (MenuName.Contains("测试"))
{
(win.DataContext as MainViewModel).OpenNewItem<UserControls.Control_Test, UserControls.TestModel>(MenuName, MenuName);
}
else
{
UserControls.TestModelSec m = new UserControls.TestModelSec(MenuName);
(win.DataContext as MainViewModel).OpenNewItemPara<UserControls.Control_Test>(MenuName, MenuName, m);
}
break;
}
}
}


  初始化菜单,在“主菜单”中有四个子菜单,其中“操作”的子菜单中还有子菜单

private void LoadMenuData()
{
MenuItem mainMenu = new MenuItem("主菜单");
MenuItem projectMenu = new MenuItem("项目");
MenuItem toolMenu = new MenuItem("工具");
MenuItem otherMenu = new MenuItem("其他");
MenuItem helpMenu = new MenuItem("帮助");

mainMenu.Childrens.Add(new MenuItem("打开"));
mainMenu.Childrens.Add(new MenuItem("新建"));

MenuItem operateMenu = new MenuItem("操作");

MenuItem saveMenu = new MenuItem("保存");
MenuItem deleteMenu = new MenuItem("删除");
MenuItem readMenu = new MenuItem("读取");
operateMenu.Childrens.Add(saveMenu);
operateMenu.Childrens.Add(deleteMenu);
operateMenu.Childrens.Add(readMenu);

mainMenu.Childrens.Add(operateMenu);

mainMenu.Childrens.Add(new MenuItem("测试三"));

helpMenu.Childrens.Add(new MenuItem("测试一"));
helpMenu.Childrens.Add(new MenuItem("测试二"));
helpMenu.Childrens.Add(new MenuItem("测试三"));

MenuList.Add(mainMenu);
MenuList.Add(projectMenu);
MenuList.Add(toolMenu);
MenuList.Add(otherMenu);
MenuList.Add(helpMenu);

SetMenuCommand(MenuList);
}


  在构造中,执行初始化菜单的方法

public MenuControlModel()
{
LoadMenuData();
}


结束

  Tab每项的内容必须为UserControl,UserControl无需与Model进行banding。测试的UserControl和其Model没有写,只是一个简单的例子~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: