2016-08-26 27 views
1

动态引用WPF菜单项如何动态地引用WPF菜单项,在VB.net我如何在VB.net

我有我的主窗口模板中,我Application.xaml菜单(请参见XAML代码如下)。在我所有的窗口中,我通过设置窗口的style =“(DynamicResource WindowTemplateMain}”来“调用”这个模板。我想要做的是根据每个菜单项的访问权限动态设置“isEnabled”属性。我可以得到所有的权限,并通过它们循环就好了。我的问题,对于WPF来说是相当新颖的,是如何引用任何给定的菜单项,以便我可以更改“isEnabled”属性?

例如,我的菜单如下,假设我想禁用菜单项“mnu_TimeEntry”。如何引用“mnu_TimeEntry”以将“isEnabled”属性更改为false?我需要这样做的vb代码,或者我应该处理主菜单的方式完全不同吗?

Thanks in您的帮助这里是所有相关代码:

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 

本例中的“mnu_TimeEntry”会因为未声明而引发错误。我可以将其声明为menuitem,但仍不知道如何将它链接到WPF菜单中的操作菜单项。

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

回答

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

所以基本上你的反转而不是引用菜单项的东西,这些要么查询当前用户是否有这项权利,并进行相应的功能。

+0

我很感谢你的回答。虽然它没有解决(我可以工作)我的问题,因为我的菜单是在全局样式模板中,它确实使我重新思考我是如何做事的,也许需要将菜单移出样式模板,使用主窗口来放置任何“子”窗口。我必须让属性不能只读,以便在需要时将canedit设置为true,否则我能够按照所示精确地实现您的代码。现在我并没有把它看作是我整个问题的答案,而是要为这个答案投票。 –