2017-10-03 10 views
0

コンテキストメニューに追加のメニュー項目を追加します。理想的には項目がvalidateMenuItemを使用して有効になっている:https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/MenuList/Articles/EnablingMenuItems.htmlあたりvalidateMenuItemの取得:Xamarinで生成されたアクションを使用してNSMenuItemを起動します。

[Action("validateMenuItem:")] 
    public bool ValidateMenuItem(NSMenuItem item) 
    { 
     _logger.DebugFormat("Validating {0} menu item with Action {1}", item.Title, item.Action.Name); 
     var target = item.Target; 
     var menuItem = ViewModel.ContextMenu.Where(x => x.Title == item.Title).FirstOrDefault(); 
     if (menuItem != null) { 
      return menuItem.Command.CanExecute(); 
     } 

     return false; 
    } 

。私は手動でアクションを作成した場合、これは呼び出されますが、私はそうのようなEventHandlerの割り当てた場合:

  var nsMenuItem = new NSMenuItem(menuItem.Title, 
              (sender, e) => 
      { 
       menuItem.Command.ExecuteAsync(); 
      }); 
      nsMenuItem.Target = this; 

validateMenuItemを:呼び出されません。このメソッドを使用して割り当てられたアクションは、__monomac_internal_ActionDispatcher_activatedです:https://github.com/xamarin/xamarin-macios/blob/master/src/AppKit/ActionDispatcher.cs(Rolf Bjarne Kvingeを助けてください)から。私のクラス(私は思う)でこのアクションがないので、validateMenuItemは呼び出されず、メニュー項目は決してアクティブ化されません。どうすればこの作品を作れますか? 私は

[Action("__monomac_internal_ActionDispatcher_activated:")] 
    public void MonomacInternalAction(NSObject sender) 
    { 
    } 

validateMenuItem、私のビューコントローラにこれを追加する場合:新しいアイテムのために呼び出されます。ただし、イベントハンドラはこの関数に置き換えられます。 (この問題は解決可能ではないかもしれません!)これは、アクションの問題対輸出かもしれない - 私は更新2.

const string skey = "__monomac_internal_ActionDispatcher_activated:"; 

    [Preserve, Export (skey)] 
    public void OnActivated (NSObject sender) 
    { 
     EventHandler handler = Activated; 
     if (handler != null) 
      handler (sender, EventArgs.Empty); 
    } 

を参照してくださいちょうど私がでvalidateMenuItemをごまかすことができアップデート3. https://bugzilla.xamarin.com/show_bug.cgi?id=51343

を見つけました

public override bool RespondsToSelector(ObjCRuntime.Selector sel) 
    { 
     if (sel.Name.Contains("__monomac_internal_ActionDispatcher_activated")) { 
      return true; 
     } 
     return base.RespondsToSelector(sel); 
    } 

元のイベントを呼び出す方法しか見つからない場合は、今すぐ使用してください。

答えて

0

この問題は、Xamarin.Macの実装上のバグです。https://bugzilla.xamarin.com/show_bug.cgi?id=51343です。私は回避策で終わった。イベントハンドラや各メニュー項目ごとに別々のアクションを使用する代わりに(登録方法を理解できなかった)、すべてのメニュー項目を処理する単一のアクションを作成しました。

[Action("contextAction:")] 
    public void contextAction(NSObject sender) 
    { 
     if (sender is NSMenuItem) 
     { 
      var nsMenuItem = (NSMenuItem)sender; 
      var wrapper = nsMenuItem.RepresentedObject as NSObjectWrapper; 
      if (wrapper != null) { 
       var menuItem = wrapper.Context as MenuItem; 
       if (menuItem != null) { 
        menuItem.Command.ExecuteAsync(); 
       } 
      } 
     } 
    } 

その後、

 foreach (var menuItem in ViewModel.ContextMenu) 
     { 
      var selector = new ObjCRuntime.Selector("contextAction:"); 
      var nsMenuItem = new NSMenuItem(menuItem.Title, selector, ""); 
      nsMenuItem.RepresentedObject = new NSObjectWrapper(menuItem); 

NSObjectWrapperがMonotouch: convert an Object to NSObjectから来ています。

関連する問題