如何在VB.net中动态引用WPF菜单项

时间:2016-08-26 16:00:07

标签: wpf vb.net menuitem

如何在VB.net中动态引用WPF菜单项

我的主窗口模板中的Application.xaml中有一个菜单(参见下面的XAML代码)。在我所有的其他窗口中,我通过设置窗口的style =“(DynamicResource WindowTemplateMain}”来“调用”此模板。我希望能够根据其访问权限动态设置每个菜单项的“isEnabled”属性。我可以获得所有权限并循环使用它们。我的问题,对于WPF来说还是新手,是如何引用任何给定的菜单项,以便我可以更改“isEnabled”属性?

例如,在我的下面的菜单中,假设我要禁用菜单项“mnu_TimeEntry”。如何引用“mnu_TimeEntry”以将“isEnabled”属性更改为false?我需要vb代码来执行此操作。或者我应该以完全不同的方式处理主菜单?

提前感谢您的帮助。以下是所有相关代码:

Application.xaml(我在其中创建菜单):

    <!--Global Window Template-->
    <Style x:Key="WindowTemplateMain" TargetType="{x:Type Window}">
        <Setter Property="FontSize" Value="12" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Window}">
                    <DockPanel Margin="0,0,-1.667,0.333" HorizontalAlignment="Stretch" Width="Auto">
                        <DockPanel.Background>
                            <LinearGradientBrush EndPoint="0.5,1" MappingMode="RelativeToBoundingBox" StartPoint="0.5,0">
                                <GradientStop Color="{StaticResource mwb_WindowBackgroundGradient0}" Offset="0"/>
                                <GradientStop Color="{StaticResource mwb_WindowBackgroundGradient1}" Offset="1"/>
                            </LinearGradientBrush>
                        </DockPanel.Background>
                        <Menu x:Name="MWB_MainMenu" DockPanel.Dock="Top"  IsMainMenu="True">
                            <MenuItem Header="_File">
                                <MenuItem Header="_Time Entry" Name="mnu_TimeEntry" Click="mnu_TimeEntryClick" />
                                <Separator />
                                <MenuItem Header="_Logout" Click="mnu_LogoutClick"/>
                                <Separator />
                                <MenuItem Header="_Exit" Click="mnu_ExitClick"/>
                            </MenuItem>
                            <MenuItem Header="_Reports">
                                <MenuItem Header="_Report1" />
                                <MenuItem Header="_Report2" />
                                <MenuItem Header="_Report3" />
                            </MenuItem>
                            <MenuItem Header="_Administration">
                                <MenuItem Header="_Clients" Click="mnu_ClientsClick" />
                                <MenuItem Header="Contac_ts" Click="mnu_ContactsClick" />
                                <MenuItem Header="System _Maintenance">
                                    <MenuItem Header="User Access _Group Maintenance" Click="mnu_UserGroupMaintClick"/>
                                    <MenuItem Header="System _Window Maintenance" Click="mnu_SysWinMaintClick"/>
                                </MenuItem>
                            </MenuItem>
                            <MenuItem Header="_Test Window" Click="mnu_TestWindow"/>
                        </Menu>
                        <Grid Margin="0,0,0,0" Width="Auto">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="790*"/>
                                <ColumnDefinition Width="Auto"/>
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto"/>
                                <RowDefinition Height="3*"/>
                            </Grid.RowDefinitions>
                            <ContentPresenter Grid.Row="1" Grid.Column="0"/>
                            <TextBlock Style="{StaticResource mwb_Copyright}" Grid.Row="2" HorizontalAlignment="Stretch" Grid.ColumnSpan="2" Margin="5,0,4.666,4" />
                        </Grid>
                    </DockPanel>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

示例Window.xaml(我将样式设置为窗口模板,并在.vb代码中从中引用菜单项“mnu_TimeEntry”):

<Window x:Name="MWB_TimeKeeper_Time_Entry" x:Class="MWB_TimeKeeper_Time_Entry"
    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:local="clr-namespace:MWB_TimeKeeper"
    mc:Ignorable="d"
    Title="MWB TimeKeeper - Time Entry"
    Style="{DynamicResource WindowTemplateMain}" Width="800" Height="600">
.
.
.
</Window>

vb代码显然不起作用,但显示了我想要做的概念:

Private Sub MWB_TimeKeeper_Time_Entry_Loaded(sender As Object, e As RoutedEventArgs) Handles MyBase.Loaded, MyBase.Loaded

    mnu_TimeEntry.IsEnabled = False

End Sub
在这种情况下,“pn”“mnu_TimeEntry”会抛出错误,因为它未声明。我可以将它声明为menuitem,但仍然不知道如何将它链接到WPF菜单中的操作菜单项。

再次感谢任何可以帮助这位新WPF程序员的人。

1 个答案:

答案 0 :(得分:1)

我认为您应该为用户可以执行的操作定义合约等,然后将您的UI元素映射到某些Boolean

<强>代码

Class MainWindow
    Private Sub FrameworkElement_OnLoaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
        Dim workspace As New Workspace
        workspace.User = New DefaultUser()
        DataContext = workspace
    End Sub
End Class

Public Class Workspace
    Public Property User() As IUser

    Public ReadOnly Property Text() As String
        Get
            Return "Hello, world !"
        End Get
    End Property

End Class

Public Interface IUser
    ReadOnly Property CanEdit() As Boolean
End Interface

Public NotInheritable Class DefaultUser
    Implements IUser

    Public ReadOnly Property CanEdit As Boolean Implements IUser.CanEdit
        Get
            Return False
        End Get
    End Property

End Class

<强> XAML

<Window x:Class="MainWindow"
        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:local="clr-namespace:WpfApplication5"
        mc:Ignorable="d" d:DataContext="{d:DesignInstance local:Workspace}"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="1*"/>
        </Grid.RowDefinitions>
        <Menu >
            <MenuItem DataContext="{Binding Path=User}" Header="_Edit" IsEnabled="{Binding CanEdit}" />
        </Menu>

        <TextBlock Grid.Row="1" Text="{Binding Text}" />
    </Grid>
</Window>

<强>结果

enter image description here

所以基本上你反转的东西,而不是引用菜单项,这些将询问当前用户是否具有此权限并相应地启用。