I am using a combination of XamOutlookBar, XamDockManager, TabGroupPane and some ContentPane objects.
If I instantiate a UserControl in the SelectedGroupChanged event handler of a XamOutlookBar and add it to a TabGroupPane, then (still within the SelectedGroupChanged event handler) I invoke the UserControl to perform a long operation on a BackgroundWorker thread, but set the visibility of floating ContentPanes to Hidden prior to this long operation, when I try to set the visibility of these ContentPanes to Visible after the long operation has completed (in RunWorkedCompleted), the ContentPanes don't render.
If I then select another UserControl on the TabGroupPane (previously added), then reselect the UserControl that I have the floating ContentPanes on, those ContentPanes all of a sudden appear.
After some experimentation, I found that adding a Sleep at the end of the SelectedGroupChanged event handler that was longer than the long operation invoked in the UserControl resolved the issue. However, I can't do this in my application as the long operation can vary and is unpredictable.
I have attached an example project demonstrating this. When 'Call & Alert Manager' is selected in the application, ScreenSelector.xamOutlookBar_SelectedGroupChanged instantiates CallAndAlertManager UserControl and then calls SetData() on it which takes 3 seconds. When the operation has finished, the spCallMonitor SplitPane (cpCallMonitor ContentPane) is not visible. However, if I put a 4-second Sleep at the end of ScreenSelector.xamOutlookBar_SelectedGroupChanged, it displays fine.
How can this be resolved?
Thanks,
Jason
I don't see how we are involved as all rendering is done by WPF but I can't open your zip to even see the issue. Can you reattach the project so we can see the problem being exhibited?
I was able to open the zip file when I switched to 7zip. Anyway, I see the problem you are describing now. Basically the dockmanager is not calling show on the toolwindow that would host the floating pane unless the visibility of the floating pane is visible. I'll submit an issue for this but for now you should be able to get around this by using Collapsed instead of Hidden.
I'm not too sure what you mean by it not hiding "the chrome of the toolwindow" as setting the SplitPanes' Visibility to Hidden seems to hide the SplitPane and its Content and that's all I want. Anything that is not floating I still wish to remain visible.
If you notice in the project I attached, there is a commented-out line of code at line 57 in ScreenSelector.xaml.cs. This dispatches the call that causes the SplitPanes' Visibilty to be changed and seems to resolve the issue. However, I'm not sure if this is just hacking around a more fundamental issue such as a bug with the Infragistics controls.
What do you think?
In WPF Hidden means that the element still participates in the layout - just that its visuals are not rendered. Collapsed means that the element doesn't participate in the Layout and of course isn't shown. So the correct behavior for the XDM would be to still show the ToolWindow even when the Visibility of the root split pane is hidden. What that would mean is that the chrome (i.e. the title bar of the floating window, the borders, etc.) would be shown but not the elements within the split pane. The chrome is outside the split pane - it is provided by the toolwindow. I think that in your case you really want to hide the floating window and therefore you want to set the root element's Visibility to Collapsed and not Hidden.
Ah, I see. I've changed the code to use the SplitPane.Parent (in the case of floating ContentPanes) to get the root PaneToolWindow and I now set that to Collapsed rather than setting the SplitPane itself to Hidden.
However, although setting PaneToolWindow.Visibility to Hidden resolves the original issue I was having (screens not becoming visible after the long operation), setting to Collapsed doesn't work - the floating pane is still visible during the long operation.
Any ideas? I've attached the latest version of the code.
I ended up finding a solution using XamDockManager.GetPanes() and an extension method to find the PaneToolWindow. I've attached the solution.
Sorry for not responding but I had missed the previous reply. I think the only issue is that you're still using Visibility.Hidden within the UpdateFloatingPanesVisibility. You just need to change that to Collapsed. Note, you didn't have to change the code to set the Visibility of the PaneToolWindow - doing what you were doing before would have worked (setting the Visibility of the root SplitPane) the only thing that needed to change was to change from using Hidden to Collapsed in the two places.
So just to be clear if I look at your original sample and search for Visibility.Hidden, there are 2 places that is used - the place that calls UpdateFloatingPanesVisibility and from within the UpdateFloatingPanesVisibility. Changing both of those from Hidden to Collapsed is all that is needed.
Technically you didn't even have to recurse into the SplitPane. The UpdateFloatingPaneVisibility could just be:
private void UpdateFloatingPanesVisibility(SplitPane splitPane, Visibility visibility){ Debug.Assert(XamDockManager.GetDockManager(splitPane) != null && XamDockManager.GetDockManager(splitPane).Panes.Contains(splitPane), "This method should only be called with a root SplitPane in a xamDockManager's Panes collection."); PaneLocation location = XamDockManager.GetPaneLocation(splitPane); if (location == PaneLocation.Floating || location == PaneLocation.FloatingOnly) { // For showing the screen as busy, only hide panes that are currently visible if (visibility == Visibility.Collapsed && splitPane.Visibility == Visibility.Visible) { // Tag the pane to indicate its visibility must be restored at the end of the busy operation splitPane.Tag = splitPane.Visibility; splitPane.Visibility = visibility; } // At the end of the busy operation, check the pane has been tagged to indicate to restore its visibility else if (visibility == Visibility.Visible && splitPane.Tag is Visibility && (Visibility)splitPane.Tag == Visibility.Visible) { splitPane.Tag = null; splitPane.Visibility = Visibility.Visible; } }}
if (location == PaneLocation.Floating || location == PaneLocation.FloatingOnly) { // For showing the screen as busy, only hide panes that are currently visible if (visibility == Visibility.Collapsed && splitPane.Visibility == Visibility.Visible) { // Tag the pane to indicate its visibility must be restored at the end of the busy operation splitPane.Tag = splitPane.Visibility; splitPane.Visibility = visibility; } // At the end of the busy operation, check the pane has been tagged to indicate to restore its visibility else if (visibility == Visibility.Visible && splitPane.Tag is Visibility && (Visibility)splitPane.Tag == Visibility.Visible) { splitPane.Tag = null; splitPane.Visibility = Visibility.Visible; } }}