I started out with this View:
<Window x:Class="MyApp.UI.Views.MainView"
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:MyApp.UI.Views"
mc:Ignorable="d"
Title="MyApp" Height="300" Width="500" WindowStartupLocation="CenterScreen">
<Grid>
<Button
HorizontalAlignment="Left"
VerticalAlignment="Top"
Command="{Binding ShutdownCommand}"
Content="_Exit"
Margin="390,225,0,0"
Width="75"/>
</Grid>
</Window>
Code-behind
Imports MyApp.UI.ViewModels
Namespace MyApp.UI.Views
Public Class MainView
Public Sub New(ViewModel As IMainViewModel)
Me.InitializeComponent()
Me.ViewModel = ViewModel
Me.DataContext = Me.ViewModel
End Sub
Private Sub MainView_Loaded(Sender As MainView, e As RoutedEventArgs) Handles Me.Loaded
Me.ViewModel.Load
End Sub
Private ReadOnly ViewModel As MainViewModel
End Class
End Namespace
ViewModel
Imports MyApp.UI.Commands
Namespace MyApp.UI.ViewModels
Public Class MainViewModel
Implements IMainViewModel
Public Sub New()
Me.ShutdownCommand = New DelegateCommand(AddressOf Me.Shutdown)
End Sub
Public Sub Shutdown() Implements IMainViewModel.Shutdown
Application.Current.Shutdown()
End Sub
Public Sub Load() Implements IMainViewModel.Load
End Sub
Public ReadOnly Property ShutdownCommand As ICommand
End Class
End Namespace
DelegateCommand
Imports Intexx
Namespace MyApp.UI.Commands
Public Class DelegateCommand
Implements ICommand
Public Sub New(Execute As Action(Of Object))
Me.New(Execute, Nothing)
End Sub
Public Sub New(Execute As Action(Of Object), CanExecute As Func(Of Object, Boolean))
If Execute.IsNothing Then
Throw New ArgumentNullException(NameOf(Execute))
Else
Me._CanExecute = CanExecute
Me._Execute = Execute
End If
End Sub
Public Function CanExecute(Parameter As Object) As Boolean Implements ICommand.CanExecute
Return Me._CanExecute.IsNothing OrElse Me._CanExecute(Parameter)
End Function
Public Sub Execute(Parameter As Object) Implements ICommand.Execute
Me._Execute(Parameter)
End Sub
Public Sub RaiseCanExecuteChanged()
RaiseEvent CanExecuteChanged(Me, EventArgs.Empty)
End Sub
Public Event CanExecuteChanged As EventHandler Implements ICommand.CanExecuteChanged
Private ReadOnly _CanExecute As Func(Of Object, Boolean)
Private ReadOnly _Execute As Action(Of Object)
End Class
End Namespace
Clicking the Exit
button works as expected. The application exits.
Then I added a menu:
<Window x:Class="MyApp.UI.Views.MainView"
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:MyApp.UI.Views"
mc:Ignorable="d"
Title="MyApp" Height="300" Width="500" WindowStartupLocation="CenterScreen">
<Grid>
<Menu>
<MenuItem Header="_File">
<MenuItem
Header="E_xit"
Command="{Binding ShutDownCommand}"/>
</MenuItem>
<MenuItem Header="_Help">
<MenuItem Header="_About MyApp"/>
</MenuItem>
</Menu>
<Button
HorizontalAlignment="Left"
VerticalAlignment="Top"
Command="{Binding ShutdownCommand}"
Content="_Exit"
Margin="390,225,0,0"
Width="75"/>
</Grid>
</Window>
Clicking the Exit
button still works, but clicking File=>Exit
produces no result. I didn't change anything in either my code-behind or my ViewModel.
This one is related, but not quite the same. My MenuItem
with the bound command is the child, not the parent.
What am I missing here? Why doesn't a File=>Exit
click call the bound command?
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…