Hello,
Using Infragistics2.Win.UltraWinToolbars.v10.3, I have been trying to host a custom WPF UserControl in the WinForms ribbon using a ControlContainerTool containing an ElementHost.
Whilst the designer correctly renders the component, when running the ElementHost region is rendered as an opaque blue colour. The component is there (you can type, copy text etc). But it is not visible.
Is this supported? Do you expect it to be able to work? Can you suggest anything to get it working?
Sample project: here.
I have been able to verify your results and am currently investigating if there is any way around to do this.
Meanwhile, please feel free to let me know if a question about our toolset comes up on your mind.
You could put the ElementHost in a Panel and assign the Panel to the Control property of the ControlContainerTool. It was Chris Shea who shed light on this, I tried it with your sample and it works fine.
Please do not hesitate to contact me if you need any additional assistance.
Hi Boris,
Thank you very much for your reply. In the end, we've decided to go with a Windows Forms version of the Control instead of WPF.
Since we use an abstraction layer I do not have access to the underlying Form. Therefore creating the unique backing Control for each ControlContainerTool and adding it to the ClientArea's Controls is problematic.
I would like to be able to create a custom Tool that creates and owns the underlying Control. In other words, I want to be able to offer the same behaviour as the Tools you provide.
I see that I should be able to create a class derived from ToolBase. Presumably, in order to access the IContainer in which to place my Control, I go through the Owner property.
I would be very helpful if there was a simple example showing a derived class based on ToolBase, rather than a simple refinement of one of your existing Tools.
Thank you,
Alex
I'm not sure whether there is an official way to do this. However, this approach seems to work:
using System.Runtime.Serialization;
using System.Windows.Forms;
using Infragistics.Win;
using Infragistics.Win.UltraWinToolbars;
namespace CustomTools
{
public class UniqueInstanceControlContainerTool : ControlContainerTool
public override Control Control { get; set; }
public UniqueInstanceControlContainerTool(string key) : base(key)
Control = new TextBox();
}
public UniqueInstanceControlContainerTool(SerializationInfo info, StreamingContext context) : base(info, context)
protected override ToolBase Clone(bool cloneNewInstance)
var tool = new UniqueInstanceControlContainerTool(Key);
tool.InitializeFrom(this, true);
return tool;
private UIElement GetControlContainerToolUIElement(ToolBase tool, UIElement parentElement, UIElement previousElement, bool drawAsActive, bool drawAsPressed)
var containerToolUiElement = new ControlContainerToolUIElement(parentElement, tool, Control);
return (UIElement)containerToolUiElement;
protected override UIElement GetRibbonToolUIElement(ToolBase tool, UIElement parentElement, UIElement previousElement, bool drawAsActive, bool drawAsPressed)
return GetControlContainerToolUIElement(tool, parentElement, previousElement, drawAsActive, drawAsPressed);
protected override UIElement GetToolbarUIElement(ToolBase tool, UIElement parentElement, UIElement previousElement, bool drawAsActive, bool drawAsPressed)
protected override bool IsContainedControlShared
get { return false; }
protected override ToolBase ToolWithContainedControl
get { return this; }
Hello acollins,
Thank you for your feedback. I believe that this could be in a great assistance to our community members. I am glad to hear that you were able to find such approach.
I have discovered two problems with this approach:
- The widget is always being displayed on top. If you change to another tab, the widget is still on top;
- I cannot seem to remove the widget.
Do you have any suggestions on how to overcome these issues?
Answering my own question again, in case others also desire this functionality. The only approach I have found to work is hooking the AfterRibbonTabSelected event. Giving something like this:
using System;
public override Control Control
get
SynchronizeVisibleSetting();
return UnderlyingControl;
public UniqueInstanceControlContainerTool(string key)
: base(key)
public UniqueInstanceControlContainerTool(SerializationInfo info, StreamingContext context)
: base(info, context)
protected override void Initialize(ToolsCollectionBase parentCollection)
base.Initialize(parentCollection);
RegisterEvents();
private void RegisterEvents()
if (ToolbarsManager != null)
// This allows us to show/hide the underlying Control to the tab it is located on.
// Strangely, this doesn't seem to be natively supported by the underlying ControlContainerToolUIElement.
ToolbarsManager.AfterRibbonTabSelected += ToolbarsManagerOnAfterRibbonTabSelected;
private void ToolbarsManagerOnAfterRibbonTabSelected(object sender, RibbonTabEventArgs ribbonTabEventArgs)
private UIElement GetControlContainerToolUIElement(ToolBase tool, UIElement parentElement,
UIElement previousElement, bool drawAsActive,
bool drawAsPressed)
return containerToolUiElement;
protected override UIElement GetRibbonToolUIElement(ToolBase tool, UIElement parentElement,
protected override UIElement GetToolbarUIElement(ToolBase tool, UIElement parentElement,
protected override void OnSubObjectPropChanged(PropChangeInfo propChange)
base.OnSubObjectPropChanged(propChange);
protected override void OnVisibleChanged()
base.OnVisibleChanged();
private void SynchronizeVisibleSetting()
var sourceTool = this as ToolBase;
var control = UnderlyingControl;
Type expectedParentType = typeof (UltraToolbarsDockArea);
UltraToolbarsManager toolbarsManager = sourceTool.ToolbarsManager;
if (toolbarsManager == null)
return;
if (control == null)
var ribbonGroup = sourceTool.Owner as RibbonGroup;
if (ribbonGroup != null)
RibbonTab tab = ribbonGroup.Tab;
if (tab != null)
if (tab != toolbarsManager.Ribbon.SelectedTab)
control.Visible = false;
if (!sourceTool.VisibleResolved)
if (!control.Visible)
else
if (control.Visible || sourceTool.UIElement == null)
Control parent = control.Parent;
if (parent == null || !expectedParentType.IsAssignableFrom(parent.GetType()))
control.Visible = true;
I've now (thankfully) resolved this issue. It came down to a misunderstanding over the lifecycle of the Control. The Control is disposed when the ribbon is minimized.
Remove the overridden get-UIElement-related methods and instead lazily rebuilding the Control resolved the issue.
Best wishes,
Hello Alex,
Please attach a sample project of this, since I am not sure already how to reproduce your scenario and we will investigate this for you.
Boris,
I wonder whether you can help with a further issue that has arisen?
If the ribbon is minimized and the tab containing the widget is clicked (to reveal the tab's tools), the element is sometimes displayed in the wrong position.
It is as if the widget is being repositioned to an offset relative to the Form's origin, rather than an offset on the ribbon tab's origin.
Any suggestions to fix this?
Thank you for your feedback again.
Please feel free to let me know if a question about our toolset comes up on your mind.