从零开始搭建Wpf基础5-无限级菜单MVVM实现

AIStudio框架汇总及介绍

前言:添加菜单控制

第一步:在MainWindow主窗口中添加一行,放置菜单,菜单项在xaml中编码,MenuItem的Command采用MVVM的绑定方法。

<Grid>
      <Grid.RowDefinitions>
          <RowDefinition Height="Auto"/>
          <RowDefinition/>
      </Grid.RowDefinitions>
      <Menu x:Name="MenuControl" Background="Transparent">
          <MenuItem Header="菜单">
              <MenuItem Header="Login" Command="{Binding MenuCommand}" CommandParameter="LoginView" />
              <MenuItem Header="Introduce" Command="{Binding MenuCommand}" CommandParameter="IntroduceView" />
          </MenuItem>
      </Menu>
      <ContentControl Grid.Row="1" prism:RegionManager.RegionName="MainContentRegion"/>
  </Grid>

第二步,在MainWIndowViewModel中,添加MenuCommand的命令方法,点击不同的菜单切换不同的界面。

class MainWindowViewModel : BindableBase
{
    IContainerExtension _container;
    IRegionManager _regionManager;

    public MainWindowViewModel(IContainerExtension container, IRegionManager regionManager)
    {
        _container = container;
        _regionManager = regionManager;

    }

    private ICommand _menuCommand;
    public ICommand MenuCommand
    {
        get
        {
            return this._menuCommand ?? (this._menuCommand = new DelegateCommand<string>(para => this.Menu(para)));
        }
    }



    private void Menu(string viewname)
    {
        _regionManager.RequestNavigate("MainContentRegion", viewname);
    }
}

第三步,菜单在xaml中写死,不够灵活,比如根据不同的用户获取不同的菜单,菜单也用绑定的方法实现。建立一个菜单类,因为菜单是树形结构,所以需要Children嵌套类,实现无限级的菜单。

public class AMenuItem : BindableBase
{
    private string _glyph;
    public string Glyph
    {
        get { return _glyph; }
        set
        {
            SetProperty(ref _glyph, value);
        }
    }

    private string _label;
    public string Label
    {
        get { return _label; }
        set
        {
            SetProperty(ref _label, value);
        }
    }

    public string Code { get; set; }//区分点击的菜单
    public int Type { get; set; }//区分菜单还是目录

    private ICommand _command;
    public ICommand Command
    {
        get { return _command; }
        set
        {
            SetProperty(ref _command, value);
        }
    }

    private ObservableCollection<AMenuItem> _children = new ObservableCollection<AMenuItem>();

    public ObservableCollection<AMenuItem> Children
    {
        get { return _children; }
        set
        {
            SetProperty(ref _children, value);
        }
    }

    public void AddChildren(AMenuItem child)
    {
        this.Children.Add(child);
    }
}

第四步 MainWindow的菜单部分代码改成:

<Menu x:Name="MenuControl" ItemsSource="{Binding MenuItems}" ItemContainerStyle="{StaticResource MenuItemStyle}"  Background="Transparent"/>

还需要改下样式部分

<!--顶部菜单栏-->
<HierarchicalDataTemplate DataType="{x:Type model:AMenuItem}" ItemsSource="{Binding Path=Children}">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>

        <TextBlock x:Name="Header" Grid.Column="1" Margin="5,0,0,0"
                        VerticalAlignment="Center"
                        Text="{Binding Label}" />
    </Grid>
</HierarchicalDataTemplate>
<!--顶部菜单-->
<Style x:Key="MenuItemStyle" TargetType="{x:Type MenuItem}" BasedOn="{StaticResource MahApps.Styles.MenuItem}">
    <Setter Property="MenuItem.Command" Value="{Binding Command}"/>
    <Setter Property="MenuItem.CommandParameter" Value="{Binding Code}"/>         
</Style>

第五步 在MainWIndowViewModel生成菜单集合

private ObservableCollection<AMenuItem> _menuItems = new ObservableCollection<AMenuItem>();
public ObservableCollection<AMenuItem> MenuItems
{
    get { return _menuItems; }
    set
    {
        SetProperty(ref _menuItems, value);
    }
}

private void InitMenu()
{
    AMenuItem menu = new AMenuItem() { Label = "菜单", Type = 0 };
    MenuItems.Add(menu);

    menu.AddChildren(new AMenuItem() { Label = "Login", Code = "LoginView", Type = 1, Command = new DelegateCommand<string>(para => this.Menu(para)) });
    menu.AddChildren(new AMenuItem() { Label = "Introduce", Code = "IntroduceView", Type = 1, Command = new DelegateCommand<string>(para => this.Menu(para)) });
}

好了,运行看效果

后续:下一章将实现,主界面。

源码地址:https://gitee.com/akwkevin/aistudio.-wpf.-client.-stepby-step

另外推荐一下我的Wpf客户端框架:https://gitee.com/akwkevin/aistudio.-wpf.-aclient

posted @ 2021-08-08 11:49  竹天笑  阅读(1506)  评论(0编辑  收藏  举报