Я начал с этого представления:
<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>
Код программной части
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
Нажатие кнопки Exit
работает должным образом. Приложение закрывается.
Затем я добавил меню:
<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>
Нажатие кнопки Exit
по-прежнему работает, но нажатие File=>Exit
не дает результата. Я ничего не менял ни в моем коде программной части, ни в моей ViewModel.
Этот имеет отношение, но не совсем то же самое. Мой MenuItem
со связанной командой - это дочерний элемент, а не родитель.
Что мне здесь не хватает? Почему нажатие File=>Exit
не вызывает привязанную команду?