-4

I have a Winform .dll referenced inside my WPF project. Main method of .dll has a parameter for passing a Control object. I need to pass reference of WPF Button control inside that method parameter, but I receieve error : "Value of type 'Button' cannot be converted to 'Control'".

As far as I've seen I can't do that because WPF and Winform controls are entirely different things, but Is there anything I can do ?

P.S.: Main .dll method opens WinForm window next to specified control (WPF control in this case), that is why I need reference of WPF control.

Lucy82
  • 654
  • 2
  • 12
  • 32
  • you could use the context menue in WPF to achive the same thing. Maybe try to explain a little more what this DLL does so we can help. What is inside the window you open with that DLL? – Denis Schaf Oct 07 '19 at 12:30
  • @DenisSchaf, .dll is just a simple Winform window with Textbox. When I enter value into Textbox, something saves in DB. But that is completely separate thing as WPF project...My problem is that .dll method contains Control parameter, which ensures that Winform window opens where I want. – Lucy82 Oct 07 '19 at 12:35
  • do you have the code for the dll so you can add a new function call or constructor that works with WPF controls? – Denis Schaf Oct 07 '19 at 12:37
  • @DenisSchaf, no I don't, I'm relatively new to WPF so that is why I asked. What Using Class declaration should I use in order to make this, or any examples ? – Lucy82 Oct 07 '19 at 12:46
  • Possible duplicate of [Using a custom WPF control in WinForms](https://stackoverflow.com/questions/535812/using-a-custom-wpf-control-in-winforms) – Peter Duniho Oct 07 '19 at 15:40
  • Unless this is a hard-to-reimplement custom control, you would be better off just using whatever the Winforms equivalent for the functionality is. But if you must use WPF controls in Winforms code, you can. See proposed duplicate. That said, my advice would be to not use Winforms at all. If there is competency in WPF, it's time to just use WPF. – Peter Duniho Oct 07 '19 at 15:42
  • @PeterDuniho, thanks for answer. But sadly that doesn't help me. I bumped into an issue where I need to add same functionality to all apps we use, and unfortunally one of them is WPF, all others are Winform. That is why .dll was designed in Winform at first place. **Elementhost and WindowsFormHost** are features that enables you to add controls in your project, but I don't need that. What I need is only to pass a reference of WPF control to Winform .dll, for calculating location of that control - in order to open .dll window in specific place... As I investigated, this can't be done. – Lucy82 Oct 08 '19 at 06:47

2 Answers2

1

Honestly, the best, easiest, cleanest solution is to make another version of the Main method which accepts System.Windows.Controls.Control instead of System.Windows.Forms.Control. They can even be overloaded (share the same name). The changes to this new version would probably be very few and simple.

However, assuming Main is some huge, complicated method that would be a nightmare to even look at- or you don't have the source code anymore- and you really have to use the existing method, there is one other potential option:
Make a class that inherits from System.Windows.Forms.Control which will act as a wrapper around a System.Windows.Controls.Control. You can use new and/or override keywords to replace the existing properties in System.Windows.Forms.Control and instead expose the equivalent properties of System.Windows.Controls.Control.

To give a rushed example:

    class WinformsControlWrapper : System.Windows.Forms.Control
    {
        protected System.Windows.Controls.Control WrappedControl;

        public WinformsControlWrapper(System.Windows.Controls.Control wrappedControl)
        {
            WrappedControl = wrappedControl;
        }

        public new int Width
        {
            get { return (int)WrappedControl.Width; }
            set { WrappedControl.Width = value; }
        }
    }

Of course there are numerous problems even with the above example: the fact that WPF uses double and winforms uses int, and the fact that WPF has both Width and ActualWidth to name a couple. But you should probably be able to write your class to work the way you need it to.

Again, making another version of Main is a much simpler, cleaner and probably easier solution. But if you really can't the above tactic should work.

Keith Stein
  • 6,235
  • 4
  • 17
  • 36
  • thanks for your answer and your example. As It turned out I bumped into some serious problems, so I decided to write a new Main method as you suggested. Will post an answer later. – Lucy82 Oct 15 '19 at 14:10
0

My solution was to change Main .dll method. Instead of passing Control object I changed parameter to accept Point object - which Is what I need in the end from a control, to get their X and Y coordinates... However WPF and Winform uses different Point library references (System.Drawing.Point and System.Point) which are different types so when calling .dll in WPF I had to convert WPF Point object into type that Winform System.Drawing.Point accepts. That was easiest I could come with.

Lucy82
  • 654
  • 2
  • 12
  • 32