I've got an application in WPF in which I want to make some controls draggable on the canvas. I know there is a Nuget package Control.Draggable for Windows.Forms but it conflicts with my WPF code:
using System.Windows.Forms;
public partial class MainWindow : Window
{
System.Windows.Controls.Button newButton = new System.Windows.Controls.Button();
ControlExtension.Draggable(newButton, true);
}
Error message underlining newButton:
Cannot convert from 'System.Windows.Controls.Button' to
'System.Windows.Forms.Control'
Is there any way to overcome this error and easily apply draggable feature in WPF?
You may want to check out dong-wpf-dragdrop. It's an open-source library that makes it easy to implement and use drag-and-drop functionality in WPF.
Related
I have a WPF solution built with VS 2015 composed of several projects. Suddenly I started receiving a warning in design mode stating the following:
The type 'Window' does not support direct content.
I understand how some controls do not support direct content, but System.Windows.Window should. I get the same warning with UserControl, and as far as I know, any other control that typically supports direct content.
Everything compiles and runs fine, but having the blue underlines through all of my XAML is bothersome. Has anyone else come across this?
Below is a screenshot:
Make sure you reference System.Xaml. Clean and rebuild the project. Works on VS 2015 Update 1.
At least in a WPF IronPython project, adding the System.Xaml reference to the project solved the problem for me:
An important thing to note here is that adding seemingly any reference will make the problem go away temporarily -- until Visual Studio is restarted. System.Xaml, on the other hand, appears to keep the problem at bay. I even tried removing the reference, whereafter the problem returned upon restarting Visual Studio.
For me this error was happening because I added a WPF Window to a class library project.
For some reason (unknown by me), Visual Studio doesn't give us the option to select the WPF Window template from the "Add New Item..." dialog box if the project was not created as a WPF Application. Instead, it only offers the option to add a WPF User Control. Because of that, I selected the User Control template for the new item, and then edited the source code to make the XAML to become a Window object rather than a User Control.
<!-- The new item was created as an UserControl, but what I needed was a Window object. -->
<UserControl>
...
</UserControl>
<!-- Changed it to Window and made other necessary adjustments. -->
<Window>
...
</Window>
The problem was actually in the code-behind. Since it was created as an User Control, the window partial class was inheriting from UserControl, like the following:
public partial class MyWindow : UserControl
{
public MyWindow ()
{
InitializeComponent();
}
}
To fix it I just had to remove the inheritance, making my window class inherith from nothing, like this:
public partial class MyWindow
{
public MyWindow ()
{
InitializeComponent();
}
}
After removing the inheritance, Visual Studio didn't show the error "The type 'Window' does not support direct content." anymore.
on behalf of #mark Richman I edited the Itemtemplate to automatically Reference "System.Xaml".
Just in case some is interested:
can be found in: "[VS InstallDir]\Common7\IDE\ItemTemplates\VisualBasic\WPF\[InputLocale]\WPFWindow"
BR,
Daniel
Add System.Xaml and UIAutomationProvider references to your project, after that clear solution and then build again
in Visual studio 2019 :
I searched for ( System.Xaml.dll )
and I added it as a reference
its worked well
found it in this location:
" C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.8 "
I have this problem that My WPF App in its MainWindow:
public partial class MainWindow : Window, ICallbackNotify
this " ICallbackNotify " is to communicate with MapInfo COM
and to assure The interactivity between UI & MapInfo
public interface ICallbackNotify : ISynchronizeInvoke
{
// Method called by MapInfoCallback class when user chooses custom OLE menuitem
void OnMenuItemClick(uint id);
// Method called by MapInfoCallback class when the status bar text changes
void OnStatusBarTextChanged(string text);
// Method called by MapInfoCallback class when window changes
void OnWindowContentsChanged(uint windowId);
}
The problem is, this code is working just fine in Windows From but when i put it into WPF there is an ERROR msg :
Error 1 'WpfApplication3.MainWindow' does not implement interface member 'System.ComponentModel.ISynchronizeInvoke.InvokeRequired' c:\users\dragon\documents\visual studio 2010\Projects\WpfApplication3\WpfApplication3\MainWindow.xaml.cs 25 26 WpfApplication3
and i cant figure out why or how to solve this problem
Under the hood Windows Forms and WPF are very different.
ISynchronizeInvoke is a Windows Form concept built upon Win32 API that doesn't apply to WPF. In WPF, we use the Dispatcher for communicating between threads.
From your question it sounds like what you want to do is host a WinForms COM control inside a WPF application. In order to bridge these two technologies, Microsoft has a WindowsFormHost control that you can use to contain your component. This blog post has a pretty good write up on that. Checkout this MSDN example: https://msdn.microsoft.com/en-us/library/vstudio/ms751761(v=vs.100).aspx
Update:
It sounds like the problem you are having isn't at runtime but during compilation?? Let slow down and be clear:
In Windows Forms, all user controls and windows implement ISynchronizeInvoke. WPF isn't built on the traditional Win32 WinProc message pump, so they do not implement this interface. If you copy and paste your INotifyCallBack interface and implementation "as is" into the MainWindow.xaml.cs, you will get a compilation error because the base interface ISynchronizeInvoke is not implemented in that class. To bypass the compilation error you will have to implement the ISynchronizeInvoke signature:
public partial class MainWindow : Window, ISynchronizeInvoke
{
public IAsyncResult BeginInvoke(Delegate method, object[] args)
{
throw new NotImplementedException();
}
public object EndInvoke(IAsyncResult result)
{
throw new NotImplementedException();
}
public object Invoke(Delegate method, object[] args)
{
throw new NotImplementedException();
}
public bool InvokeRequired
{
throw new NotImplementedException();
}
}
But guess what? If you do this, it's up to you to provide the proper mapping between ISynchronizeInvoke and the WPF Dispatcher. So don't do this! The above code might compile but it likely won't work correctly (or at all).
Instead, use the Windows Form Integration capabilities provided by Microsoft to host your control inside a WindowsFormHost control. As you need to implement custom code in your INotifyCallback, you'll need to put that code into a custom windows forms user control.
All said, you need to follow the direction provided by the article listed above:
Reference System.Windows.Forms.dll and WindowsFormsIntegration.dll
Add the appropriate namespaces to your MainWindow.xaml
Add the WindowsFormsHost as a container into your MainWindow.xaml, and then put your custom control inside of that.
So instead of putting your ICallbackNotify implementation on the WPF MainWindow, put it in a standard Windows Form UserControl:
namespace YourProject {
using System.ComponentModel;
using System.Windows.Forms;
public class MyCustomMapControl : UserControl, ICallbackNotify
{
// your custom code goes here
}
}
I would like to create a Silverlight custom control using C# only, without any xaml.
Here is my work so far (stripped down to the bare minimum for the question):
I tried to inherit User control as follows:
public class myControl: UserControl
{
// class code
}
And adding it to the LayoutRoot:
myControl control = new myControl();
LayoutRoot.Children.Add(control);
The control is added, but its invisible!!
How can i make it visible ? Is there something i missed ?
edit: The only visual element in my contorl is a grid with an image background
Your Usercontrol will be empty and have no visual effect until you give it a child control via it's Content property.
Well unless you put a template in place or add elements in code, UserControl is empty.
Maybe you could try inheriting from an existing control which has a template, like Button, etc and change that in code?
I am making a Excel Addin in VS2010.
The following code work fines if I make a winforms usercontrol
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
var testControlView1 = new UserControl1();
var MyCustomPane = this.CustomTaskPanes.Add(testControlView, "Hello");
}
However I would like to make my UserControl1 be a WPF UserControl. Does anybody know how I would achieve similar functionality or an alternate approach?
As far as I can tell the CustomTaskPanes only allows Winforms Controls to be added to it.
Answer summary:
1. Add a .net winforms usercontrol
2. Add a SWF.Integration.ElementHost control to the user control.
3. Add a Wpf control to your project seperately (not to the user control).
3. Use the Hosted Content property (hostedcontentName) of the ElementHost control and set it to the wpf control.
I found this blog post that answered it great...
I am planning to create a WPF application with a main window which would launch various WinForms. Some of the WinForms use the System.Windows.Forms.Application class (DoEvents, Application.Path, etc). Do you think that there will be a problem in doing this?
Can I still use System.Windows.Forms.Application.DoEvents() from a WinForm that is launched from a WPF application?
The main problem will the ability to instantiate the Windows Forms window and set it's owner to that of the WPF window. The Winforms will want a IWin32Window which a WPF window isn't. To get around this, you need to make a custom class.
I found this code on Mark Rendle's blog (I've copied it here as I had to use the Google Cache to access the page).
LINK - WARNING: May not work
class Shim : IWin32Window
{
public Shim(System.Windows.Window owner)
{
// Create a WindowInteropHelper for the WPF Window
interopHelper = new WindowInteropHelper(owner);
}
private WindowInteropHelper interopHelper;
#region IWin32Window Members
public IntPtr Handle
{
get
{
// Return the surrogate handle
return interopHelper.Handle;
}
}
#endregion
}
and it's method of use:
namespace System.Windows.Forms
{
public static class WPFInteropExtensions
{
public static DialogResult ShowDialog(
this System.Windows.Forms.Form form,
System.Windows.Window owner)
{
Shim shim = new Shim(owner);
return form.ShowDialog(shim);
}
}
}
I haven't tested this code, but reading around the internet, it appears that you can host Winforms windows inside of a WPF app.
I just found this link on MSDN that has a very detailed description of how to interop a Win32 control/window in a WPF application.
Hope these help you out.
I've been doing this sometimes and didn't encounter any problem.
However i don't really recommend it, you should prefer WPF when you are in a WPF Application.
for exemple if you want application path use this :
System.Reflection.Assembly.GetExecutingAssembly().Location