locked
Why does command become inactive? RRS feed

  • Question

  • The project contains lots of UserControls that get showed when a menu command is clicked. Command handler acts like this - it clears children of the grid element in the main window and adds new UserControl instance to the grid's children.

     

    But when focus is set in the UserControl's element and command in the menu is clicked, all menu commands become inactive.

     

    I guess it has something to do with the loss of the logical focus on the old UserControl's delete. But why then FocusManager.FocusedElement isn't working? And why menu commands are active on startup?

     

    How to make menu command always active? I think that setting focus in UserControl's Loaded handler is not the right decision.

     

    Code to download: http://depositfiles.com/files/pkl1uhobf

     

    Code:


    MainWindow.xaml

    <Window x:Class="Wpf_Tester.MainWindow" 
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:controls="clr-namespace:Wpf_Tester" 
        Title="Window" Height="160" Width="310"
        <StackPanel> 
            <Menu> 
                <MenuItem Command="controls:SomeUserControl.ShowCommand" /> 
            </Menu> 
            <Grid Name="grid" /> 
        </StackPanel> 
    </Window> 


    MainWindow.xaml.cs

    using System.Windows; 
    using System.Windows.Input; 
     
    namespace Wpf_Tester 
        public partial class MainWindow: Window 
        { 
            public MainWindow( ) 
            { 
                InitializeComponent( ); 
     
                CommandBindings.Add( new CommandBinding( SomeUserControl.ShowCommand, delegate 
                { 
                    grid.Children.Clear( ); 
                    grid.Children.Add( new SomeUserControl( ) ); 
                } ) ); 
     
                SomeUserControl.ShowCommand.Execute( nullthis ); 
            } 
        } 

    SomeUserControl.xaml

    <UserControl x:Class="Wpf_Tester.SomeUserControl" 
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
        Loaded="UserControl_Loaded" 
        >     
        <!-- Doesn't work when added to UserControl --> 
        <!-- FocusManager.FocusedElement="{Binding ElementName=firstTextBox}" --> 
        <Grid> 
            <TextBox Name="firstTextBox" Text="Set mouse focus on me and click on menu" /> 
        </Grid> 
    </UserControl> 
     

    SomeUserControl.xaml.cs

    using System.Windows.Controls; 
    using System.Windows.Input; 
     
    namespace Wpf_Tester 
        public partial class SomeUserControl: UserControl 
        { 
            public static RoutedUICommand ShowCommand = new RoutedUICommand( 
                "Show SomeUserControl"
                "Show"
                typeof( SomeUserControl ) ); 
     
            public SomeUserControl( ) 
            { 
                InitializeComponent( ); 
     
                // doesn't work
                //firstTextBox.Focus( ); 
            } 
     
            private void UserControl_Loaded( object sender, System.Windows.RoutedEventArgs e ) 
            { 
                // does work, but IMHO it's wrong solution
                //firstTextBox.Focus( );  
            } 
        } 



    Wednesday, February 18, 2009 3:06 PM

Answers

  • It seems you've encountered the dreaded focus nightmare. Many people have discussed this problem and its workarounds here:

    http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/f5de6ffc-fa03-4f08-87e9-77bbad752033

    I hope this helps.
    • Marked as answer by FallenGameR Thursday, February 19, 2009 3:25 PM
    Wednesday, February 18, 2009 4:22 PM
  • Thanks. The link helped.
    When CommandTarget is set explicitly it works.
    Though it doesn't seem to be an elegant solution:

    CommandTarget="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"

    Is there other way?

    PS CommandTarget="{Binding ElementName=menu}" is not working (because menu is not focusable I guess).
    PPS CommandTarget="{Binding ElementName=window}" is not applicable when menu is separated in new UserControl.


    • Marked as answer by FallenGameR Thursday, February 19, 2009 3:25 PM
    Wednesday, February 18, 2009 5:44 PM

All replies

  • It seems you've encountered the dreaded focus nightmare. Many people have discussed this problem and its workarounds here:

    http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/f5de6ffc-fa03-4f08-87e9-77bbad752033

    I hope this helps.
    • Marked as answer by FallenGameR Thursday, February 19, 2009 3:25 PM
    Wednesday, February 18, 2009 4:22 PM
  • Thanks. The link helped.
    When CommandTarget is set explicitly it works.
    Though it doesn't seem to be an elegant solution:

    CommandTarget="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"

    Is there other way?

    PS CommandTarget="{Binding ElementName=menu}" is not working (because menu is not focusable I guess).
    PPS CommandTarget="{Binding ElementName=window}" is not applicable when menu is separated in new UserControl.


    • Marked as answer by FallenGameR Thursday, February 19, 2009 3:25 PM
    Wednesday, February 18, 2009 5:44 PM
  • That's the solution I use myself. I haven't found a better one.
    Thursday, February 19, 2009 2:21 PM