WPF Microsoft Ribbon Control does not work with FocusManager?

1.3k views Asked by At

I have a problem where I cannot get the FocusManager to recognize when a Ribbon Control has the focus.

The logic is simple. I put the focus on a text box. I have tried both a RibbonText and Textbox. I see that when I click the Textbox the GotFocus event fires showing that it now has the focus. When I move the mouse on the canvas it should update the Textbox but this does not happen. The FocusManager.GetFocusedElement returns null. I tried this with a Statusbar and added a Textbox. Using a Statusbar the GetFocusedElement returns the Textbox.

This exact same code worked when I had used a grid with two columns. The Grid had a a canvas on the left column and a stackpanel with several expander controls with text boxes in them on the right column. The right was getting too busy with too many expander controls so I switched to the Ribbon Control since the multiple tabs and other features made it an optimal choice.

I have tried all combinations of setting "Focusable" but it does not help

<ribbon:RibbonWindow x:Class="WpfRibbonApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:ribbon="clr-namespace:Microsoft.Windows.Controls.Ribbon;assembly=RibbonControlsLibrary"
        Title="MainWindow" x:Name="RibbonWindow" Width="640" Height="480">
    <Grid x:Name="LayoutRoot">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <ribbon:Ribbon x:Name="Ribbon">
            <ribbon:Ribbon.ApplicationMenu>
                <ribbon:RibbonApplicationMenu SmallImageSource="Images\SmallIcon.png">
                    <ribbon:RibbonApplicationMenuItem Header="Hello _Ribbon" x:Name="MenuItem1" ImageSource="Images\LargeIcon.png"/>
                </ribbon:RibbonApplicationMenu>
            </ribbon:Ribbon.ApplicationMenu>
            <ribbon:RibbonTab x:Name="HomeTab" 
                              Header="Home">
                <ribbon:RibbonGroup x:Name="Group1" 
                                    Header="Group1">
                        <TextBox Name="Try" Width="200" GotFocus="Try_GotFocus"></TextBox>                   
                </ribbon:RibbonGroup>               
            </ribbon:RibbonTab>
        </ribbon:Ribbon>
        <Canvas Grid.Row="1" Height="250" Margin="0,5,0,0" Name="canvas1" Background="AliceBlue" VerticalAlignment="Top" MouseMove="canvas1_MouseMove" />
    </Grid>
</ribbon:RibbonWindow>


using Microsoft.Windows.Controls.Ribbon;

namespace WpfRibbonApplication1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : RibbonWindow
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void canvas1_MouseMove(object sender, MouseEventArgs e)
        {
                if (e.LeftButton == System.Windows.Input.MouseButtonState.Pressed)
                {
                    System.Windows.Point p = e.GetPosition(canvas1);
                    var fe = FocusManager.GetFocusedElement(this);   
                    if (fe != null)
                    {
                        var element = fe as FrameworkElement;

                        if (element.Name == "Try")
                        {
                            Try.Text = "Canvas has Focus";
                        }
                    }
                }
        }

        private void Try_GotFocus(object sender, RoutedEventArgs e)
        {
            Try.Text = "Got Focus";
        }
    }
}
1

There are 1 answers

0
AndrewS On

The Ribbon is a focus scope - i.e. it sets its FocusManager.IsFocusScope to true just like other elements (e.g. toolbar, menu, etc.) that want to maintain their own logically focused element. Therefore you need to pass the Ribbon to the GetFocusedElement if you want to find out the logically focused element within that focus scope. If you just want the currently keyboard focused element then you can look at the Keyboard.FocusedElement. You can read more about logical focus here.