Geeks With Blogs

@franhoey
  • franhoey @ForeignHoey You set some dates for an event or something and send out the link, people can tick days they can and can't do. Very simple about 464 days ago
  • franhoey @vivslack Viv there is a place in Llangollen that does I think, I went on a Whitewater rafting thing there about 465 days ago
  • franhoey @eifion Hmm, no, I use Excel! I'll take a look. about 465 days ago
  • franhoey Yes contractors are paid more and yes even with the time doing accounts it's still worth it, but bloody hell, it drives me potty about 465 days ago
  • franhoey @realRobT79 yes we have! I'm out at the moment but if you drop me an email I'll send you the code(s) later. Fran@bluejumper.com about 466 days ago

Fran Hoey

This is a problem I've struggled and struggled with. No workaround or fix I found on the internet worked. In fact the work around I finally got to work incorporates a combination of fixes.

Symptoms

The Form or User Control designer in Visual Studio displays the following error:

Visual inheritance is currently disabled because the base class references a device-specific component or contains P/Invoke

Cause

In case you didn't know P/Invoke is used to access un-managed code (com components). The designer has to compile and initialise your forms via the constructor to display them on the design pane, however, it is unable access un-managed code. If your forms inherit from a custom base form and the designer sees a P/Invoke anywhere in your code (even if it will never access it) it throws the above error.

Two examples of this I've found are:

  • The InputPanel Control
  • The Sqlite .Net Libraries from PHX Software

See here for more - http://msdn.microsoft.com/en-us/library/ms228851.aspx

Solution

As hinted at before there are two parts to the solution. First you need to tell the designer “Don't worry about it, I wont let you touch P/Invoke code”, then you need to live up to your promise.

Part 1

Mark your base form with DesktopCompatible(true) to calm the designer.

  1. In Solution Explorer, right click your form and select "View Class Diagram".
  2. Select the class blob.
  3. In Properties Pane click "..." button in the "Custom Attributes"
  4. Paste DesktopCompatible(true) into the text area and click ok.

Part 2

Avoid code that references the P/Invoke code. There are many ways to do this but here is my simple method.

The designer pane only initialises the forms it requires. When the program runs for real, the static class Program opens the first form and your code takes it from there. That little nugget of information makes my method work.

  1. Create a static class with a static property as such
    public static bool IsRuntime { get; set; }
  2. In the Main function in the Program Class (Program.cs) set the above property to true before it opens the first form. This code is only run at runtime.
  3. Use this property in if statements in your code to avoid P/Invoke calls when IsRuntime is false.

SQLite Solution

The above solution would work if you are using SQLite, but you would end up with very messy code as you are probably referencing your SQLite libraries quite often. This is a neater solution that keeps all the runtime checks in a central place.

Part 1

Same as above.

Part 2

Create a class that sets up your SQLite Objects and perform your checks there. Unfortunately I cant publish my class here as the source code belongs to my client, however, I can give you a few snippets to give you the general idea.

1. Create an IsRuntime Property

2. Get the calling code (e.g. Form) to pass in the IsRuntime flag

3. Use Interfaces to avoid any declaration of SQLite classes and only initialise SQLite classes when IsRuntime is true.

Posted on Friday, May 6, 2011 12:36 PM Compact Framework , .Net | Back to top


Comments on this post: Compact Framework Visual Inheritance P/Invoke Designer Error

No comments posted yet.
Your comment:
 (will show your gravatar)
 


Copyright © FranHoey | Powered by: GeeksWithBlogs.net | Join free