Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
128 views
in Technique[技术] by (71.8m points)

c# - Menu click not firing its bound command

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

OK, got it.

Being a bit new to WPF, I'd forgotten that command bindings (among other things) are case sensitive.

When I change the MenuItem's command binding from ShutDownCommand to ShutdownCommand, it works. The application exits as expected.

It'd be nice if IntelliSense worked here.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...