There is an old Winforms control which I hosted in WPF app.
Control makes use of System.Windows.Forms.ListView inside and this ListView uses Groups feature.
The problem is that this control when hosted by WPF does not show groups.
I've manually compared properties of ListView when it's hosted by Winforms app and WPF app.
For both ListViews ShowGroups property is true.
However there is a property called GroupsEnabled and it's true when control is hosted in Winforms and false when it's hosted in WPF.
I've found definition here:
internal bool GroupsEnabled
{
get {
return this.ShowGroups && groups != null && groups.Count > 0 && ComctlSupportsVisualStyles && !VirtualMode;
}
}
VirtualMode is false for both but ComctlSupportsVisualStyles is true for Winforms hosting and false for WPF app.
Code of ComctlSupportsVisualStyles from the same source:
private bool ComctlSupportsVisualStyles {
get {
if(!listViewState[LISTVIEWSTATE_comctlSupportsVisualStylesTested])
{
listViewState[LISTVIEWSTATE_comctlSupportsVisualStylesTested] = true;
listViewState[LISTVIEWSTATE_comctlSupportsVisualStyles] = Application.ComCtlSupportsVisualStyles;
}
return listViewState[LISTVIEWSTATE_comctlSupportsVisualStyles];
}
}
I think I need to set Application.ComCtlSupportsVisualStyles somehow in my WPF code.
And this must be System.Windows.Forms.Application and not System.Windows.Application.
Is there any way to do it?
Enabling visual styles for your application should fix the problem:
System.Windows.Forms.Application.EnableVisualStyles();
The WinForms ListView control does not support groups unless visual styles are enabled (technically, unless version 6 of the ComCtrl32 library is used, which is the same version as required to support visual styles).
See also: How to: Enable Visual Styles in a Hybrid Application
Related
In WindowsForms each control having the AccessibilityObject. If its a custom control derived from a Control then its also having the AccessibilityObject.
How can i test the accessibility object of the custom control in windows forms.
Is there any testing tools is available to test the accessibility object?
protected override AccessibleObject CreateAccessibilityInstance()
{
if (accessibilityEnabled)
{
return new CustomControlAccessiblity(this);
}
return base.CreateAccessibilityInstance();
}
What is the usage of the custom accessibility object and how it can be used in the accessibility aids?
My setup is kinda unorthodox - The CLR is hosted in a native Win32 application. Application loads and invokes a managed assembly (written in C++/CLI). Assembly creates a Windows Forms form with a WPF ElementHost. ElementHost gets populated with a stack panel that includes an image control and label control.
The managed assembly contains embedded image resources. The name of the resource file (in the project) is 'Images' and that of the particular resource in question is 'ISIconDB'.
How do I use the aforementioned resource as the image control's source?
Figured it out.
[DllImport("gdi32.dll")] int DeleteObject(IntPtr hObject);
//Drawing::Bitmap^ OrgResource;
Windows::Media::Imaging::BitmapSource^ Marshalled = nullptr;
try {
Marshalled = System::Windows::Interop::Imaging::CreateBitmapSourceFromHBitmap(OrgResource->GetHbitmap(),
IntPtr::Zero, Windows::Int32Rect::Empty, Windows::Media::Imaging::BitmapSizeOptions::FromEmptyOptions());
}
catch (...) {
Marshalled = nullptr;
}
finally {
DeleteObject(OrgResource->GetHbitmap());
}
One of our customers hosts our WinForms .NET grid control iGrid.NET (http://www.10tec.com/) inside a WPF ElementHost container together with other WPF controls. It may look strange as it's a WinForms control inside a WPF host inside a WinForms form, but they have no choice because of the other WPF stuff they use (it's the AvalonDock http://avalondock.codeplex.com/ docking container).
The problem is that our .NET datagrid control's infrastructure requires to know the parent WinForms form, but the following construction we use for that always return null in this situation:
Form myTopLevelOwnerForm = fCurrentGrid.TopLevelControl as Form;
I.e. the standard Control.TopLevelControl property intended for this purpose returns null - though most likely it should be so in the case of WPF host.
The question is: are there other ways to know the parent form from the current control's code? Say, using WinAPI handles or better other native .NET memebrs?
The following code works. At least, in our project :)
// API declaration
[System.Runtime.InteropServices.DllImport("user32.dll", ExactSpelling = true, CharSet = System.Runtime.InteropServices.CharSet.Auto)]
public static extern IntPtr GetParent(IntPtr hWnd);
// Main code snippet
Control myTopLevelControl = fOwner.TopLevelControl;
if (myTopLevelControl == null)
{
IntPtr handle = fOwner.Handle;
while (true)
{
IntPtr parentHandle = GetParent(handle);
if (parentHandle == IntPtr.Zero)
{
myTopLevelControl = Control.FromHandle(handle) as Form;
break;
}
handle = parentHandle;
}
}
I'm developing a custom control which shows an inline popup window and I would like to use a similar technique as the TabControl employes so that only popup windows that are selected within the designer or more commonly by placing the cursor within the popup declaration in XAML that it is visualized right within the desiger without having to run the application or change any runtime values by hand.
I've started by duplicating the implementation of the TabControl which I have successfully mimicking everything but it is all copied from Reflector output and Stylesnooper. I've renamed all of the control parts and then replaced the default templates so that the main control uses an ItemsPresenter instead of a ContentPresenter to show the individual popup controls within a Grid panel overlayed on top of one another. So far this is working great too. The problem is that somewhere along the line I lost the ability to have the designer follow the item that is selected in the XAML editor.
Either an explanation of how the TabControl's design time behavior functionality actually works to describe the selected TabItem behavior that I described above or just some pointers on how one could achieve what I'm tryign to do would be great.
To solve a similar problem, I had to create design time support for my custom tab control. Here is a link for WPF Designer Extensibility.
Basically, I created a PrimarySelectionAdornerProvider to handle click interaction and a FeatureConnector<> / FeatureProvider pair for selection changes (including selection changes made in the xaml editor).
The feature provider / connector:
[FeatureConnector(typeof(AutoTabPageSelectionFeatureConnector))]
class AutoTabPageSelectionFeatureProvider : FeatureProvider
{
public AutoTabPageSelectionFeatureProvider()
: base()
{
// sole purpose is to register the connector
}
}
class AutoTabPageSelectionFeatureConnector : FeatureConnector<AutoTabPageSelectionFeatureProvider>
{
public AutoTabPageSelectionFeatureConnector(FeatureManager manager)
: base(manager)
{
SelectionOperations.Subscribe(this.Context, SelectionChanged);
}
private void SelectionChanged(Selection selection)
{
if (selection.PrimarySelection != null)
{
// navigate tree to find parent (custom tab page and custom tab control)
for (ModelItem item = selection.PrimarySelection; item != null; item = item.Parent)
{
// once found, select appropriate tab
}
}
}
}
Edit (more info):
This Microsoft link has a number of links to walk-throughs that should help. Here are the basic steps to get started:
Create a new project, MyAssembly.VisualStudio.Design.dll.
The library should compile to the same location as MyAssembly.dll (important).
Add references to Microsoft.Windows.Design.Extensibility and Microsoft.Windows.Design.Interaction.
Add a reference to your control library.
Create a class called Metadata
Code:
internal class Metadata : IProvideAttributeTable
{
// Accessed by the designer to register any design-time metadata.
public AttributeTable AttributeTable
{
get
{
AttributeTableBuilder builder = new AttributeTableBuilder();
// Add the adorner provider to the design-time metadata.
builder.AddCustomAttributes(
typeof(MyControl), // rename to your control's name
new FeatureAttribute(typeof(MyPrimaryAdornerProvider)), // rename to whatever you will call your PrimaryAdornerProvider
new FeatureAttribute(typeof(AutoTabPageSelectionFeatureProvider)) // rename to whatever you will call your SelectionFeatureProvider
);
return builder.CreateTable();
}
}
}
Create a class MyPrimaryAdornerProvider from PrimarySelectionAdornerProvider (rename to whatever you want). See link for good walk-through.
Create the AutoTabPageSelectionFeatureProvider and AutoTabPageSelectionFeatureConnector from the example above.
I have an ActiveX control (written in Delphi) which I want to host in a WPF application. When I try to load it into the toolbox to add it to the XAML at design time, it is not shown in the list of available controls. Does anyone know what filters this list and why I can't see the control to add it?
Edit
This is where I get to - the host.Child = (ax); statement gets an error (Cannot implicitly convert type 'DemoFrameControl.DemoFrameCtrl' to 'System.Windows.Forms.Control'), hope this helps clarify my problem
private void WindowLoaded(object sender, RoutedEventArgs e)
{
// Create the interop host control.
System.Windows.Forms.Integration.WindowsFormsHost host =
new System.Windows.Forms.Integration.WindowsFormsHost();
// Create the ActiveX control.
DemoFrameControl.DemoFrameCtrl ax = new DemoFrameControl.DemoFrameCtrl();
// Assign the ActiveX control as the host control's child.
host.Child = (ax);
// Add the interop host control to the Grid
// control's collection of child controls.
this.grid1.Children.Add(host);
// Play a .wav file with the ActiveX control.
//axWmp.URL = #"C:\WINDOWS\Media\Windows XP Startup.wav";
}
Thanks
Check out Walkthrough: Hosting an ActiveX Control in WPF.
Update:
How is DemoFrameCtrl defined? Like the error says, it needs to be a subclass of System.Windows.Forms.Control to use WindowsFormsHost. An ActiveX control wrapper will inherit from AxHost which inherits from Control. I think Visual Studio will generate the wrapper if you add a reference to the ActiveX library. If not, you can try using Aximp.exe (Windows Forms ActiveX Control Importer).