c# - Why is Keyboard.FocusedElement null when focus is inside WindowsFormsHost? It breaks WPF command routing -


i have custom routeduicommand mycommand gets executed via icommand.execute. top window has binding handle it:

<window.commandbindings>     <commandbinding command="local:mainwindow.mycommand" canexecute="canexecutecommmand" executed="commandexecuted"/> </window.commandbindings> 

this handler command. have windowsformshost winforms' textbox control inside (for demo purpose). when focus inside textbox, mycommand doesn't reach top window. when focus inside wpf's native textbox, command handler gets invoked expected.

i've figured out this happening because keyboard.focusedelement null when focus inside windowsformshost. why null in case, wpf bug or design feature? missing something?

i believe command should reaching top window, regardless of focus is (when it's handler in visual tree , focusmanager.isfocusscope set correctly). have related question that.

the project sources available here.

xaml:

<window x:class="wpfcommandtest.mainwindow"         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"         xmlns:local="clr-namespace:wpfcommandtest"          xmlns:wf="clr-namespace:system.windows.forms;assembly=system.windows.forms"           title="mainwindow" height="480" width="640" background="gray">      <window.commandbindings>         <commandbinding command="local:mainwindow.mycommand" canexecute="canexecutecommmand" executed="commandexecuted"/>     </window.commandbindings>      <stackpanel margin="20,20,20,20">         <textbox name="textboxoutput" focusable="true" istabstop="true" height="150" text="wpf textbox&#x0a;"/>         <windowsformshost focusable="true" keyboardnavigation.istabstop="true"  height="150">             <wf:textbox x:name="textboxwf" text="winforms textbox" />         </windowsformshost>         <button focusmanager.isfocusscope="true" name="btntest" focusable="false" istabstop="false" content="test (icommand.execute)" click="btntest_click" width="200"/>         <button focusmanager.isfocusscope="true" focusable="false" istabstop="false" content="test (command property)" command="local:mainwindow.mycommand" width="200"/>         <button focusmanager.isfocusscope="true" name="btnclearfocus" focusable="false" istabstop="false" content="clear focus" click="btnclearfocus_click" width="200"/>     </stackpanel>  </window> 

c#:

using system; using system.windows; using system.windows.input;  namespace wpfcommandtest {     public partial class mainwindow : window     {         public static readonly routeduicommand mycommand = new routeduicommand("mycommand", "mycommand", typeof(mainwindow));         const string null = "null";          public mainwindow()         {             initializecomponent();             this.loaded += (s, e) => textboxoutput.focus(); // set focus on textbox         }          void canexecutecommmand(object sender, canexecuteroutedeventargs e)         {             e.canexecute = true;         }          void commandexecuted(object sender, executedroutedeventargs e)         {             var routedcommand = e.command routedcommand;             var commandname = routedcommand != null ? routedcommand.name : null;             log("*** executed: {0} ***, {1}", commandname, formatfocus());         }          void btntest_click(object sender, routedeventargs e)         {             log("btntest_click, {0}", formatfocus());             icommand command = mycommand;             if (command.canexecute(null))                 command.execute(null);         }          void btnclearfocus_click(object sender, routedeventargs e)         {             focusmanager.setfocusedelement(this, this);             keyboard.clearfocus();             log("btnclearfocus_click, {0}", formatfocus());         }          void log(string format, params object[] args)         {             textboxoutput.appendtext(string.format(format, args) + environment.newline);             textboxoutput.caretindex = textboxoutput.text.length;             textboxoutput.scrolltoend();         }          string formattype(object obj)         {             return obj != null ? obj.gettype().name : null;         }          string formatfocus()         {             return string.format("focus: {0}, keyboard focus: {1}",                 formattype(focusmanager.getfocusedelement(this)),                 formattype(keyboard.focusedelement));         }     } } 

to complete interop form-wpf need this:

app.xaml.cs:

    public partial class app : application       {       protected override void onstartup(startupeventargs e)         {         windowsformshost.enablewindowsformsinterop();         base.onstartup(e);         }       } 

Comments

Popular posts from this blog

java - activate/deactivate sonar maven plugin by profile? -

python - TypeError: can only concatenate tuple (not "float") to tuple -

java - What is the difference between String. and String.this. ? -