We have a situation where we need to display a particular ContentPane (in a TabGroup or DocumentContentHost) without causing the application to steal the focus. We are currently using latest NetAdvantage WPF v9.2.
Unfortunately, ContentPane.Activate() internally calls Window.Activate() on the Window that contains the ContentPane, this causes the application to get focus if it does not already have it.
Is there any way to make a ContentPane visible without causing the application to steal focus?
Below is a simple test that shows the problem. When this window is running the active pane is changed every second and each time the active pane changes the application gets focus (try clicking on another application while it is running).
<UserControl x:Class="Tests.ContentPaneActivateView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:dm="clr-namespace:Infragistics.Windows.DockManager;assembly=Infragistics3.Wpf.DockManager.v9.2"> <Grid> <dm:XamDockManager> <dm:SplitPane> <dm:TabGroupPane Name="TabGroup"> <dm:ContentPane Header="Pane 1"> <RichTextBox/> </dm:ContentPane> <dm:ContentPane Header="Pane 2"> <RichTextBox/> </dm:ContentPane> <dm:ContentPane Header="Pane 3"> <RichTextBox/> </dm:ContentPane> <dm:ContentPane Header="Pane 4"> <RichTextBox/> </dm:ContentPane> </dm:TabGroupPane> </dm:SplitPane> </dm:XamDockManager> </Grid></UserControl>
namespace Tests{ [TestFixture] public class ContentPaneActivateTest { [Test] public void ShouldActivateContentPane() { var view = new ContentPaneActivateView(); var panes = view.TabGroup.Items; int index = 0; var timer = new DispatcherTimer(TimeSpan.FromSeconds(1), DispatcherPriority.Background, (o, e) => ((ContentPane) panes[index++ % panes.Count]).Activate(), Dispatcher.CurrentDispatcher); timer.Start(); new Window { Content = view }.ShowDialog(); } }}
The Activate method is intended to make that element the active pane and since the ActivePane is the one with keyboard focus it made sense to try and activate the associated window. That being said in a recent hotfix (~June-July) the Activate method was changed such that it will not activate the window if it is within a window that was disabled because a modal window was shown.
BTW if you just want to bring the pane into view then you can use the FrameworkElement's BringIntoView method on the pane or an element within the pane.
Many thanks for the quick reply and BringIntoView() is almost what I need but, unfortunately, that can result in Window.Activate calls too. I think it is due to TabGroupPane.OnSelectionChanged calling VerifyActivePanes which eventually results in calls to Window.Activate.
Is there anything else that can be done to avoid the calls to Window.Activate()?
Cheers,Leaf.
Is the active Window a modal window? If so, are you using the latest service release?
Thanks for raising the issue.
Leaf,
I will create a private support case for you and link it to Development Issue #61435 so you are notified when this fix is released. As Andrew mentioned, this fix will go back as far as v10.1, so it would require an upgrade to get it if you;re currently on v9.2.
Thanks,
I can't think of any way to prevent this. We can look into changing the RequestBringIntoView to not activate the pane but it should be noted that we're not doing fixes to 9.2 any longer so this would be something changed in 10.1 and later.
No, it is the top-level window of the application.
We have a requirement to display particular ContentPanes based on messages from other applications but without the other applications losing focus. An unusual requirement, I agree :)