In Java Swing, we can create GUI with only coding Java (for example in Eclipse). Using NetBeans's toolbox to drag and drop components to the UI is optional.
I am wondering if there is the same concept in C#. Can I put my components into my GUI and add them behaviors with only coding? That way I would feel that I have more control over my application.
Example: I do not want to g to toolbox to add "mousehover" to my button! Instead, I want to write the code myself. I know where I can find the code, but is it the only place that I should write that line of code?
Please compare Java Swing with C# in this.
Regarding C# :
In order for you to run a C# application from a cmd, following steps are needed :
Go to C:\Windows\Microsoft.NET\Framework\v4.0.30319 location on your File System and copy the path.
Now right click Computer go to Properties.
Under System Properties, select Advanced Tab, and click on Environment Variables.
On Environment Variables under User Variables, select New.
For Variable Name write CSHARP_HOME or something else, though I am using the same for further needs to explain this out. For Variable Value simply Paste what you copied in Step 1. Click OK.
Again perform Step 4, if path variable does not exist, else you can simply select path and then click Edit to perform this next thingy (after putting ;(semi-colon) at the end of the Variable Value and write %CSHARP_HOME%\(or use what you used in Step 5) ). This time for Variable Name write path, and for Variable Value use %CSHARP_HOME%\ and click OK.
Open cmd and type csc and press ENTER, you might be able to see something like this as an output
Now consider I am creating a directory structure for my CSharp Project like this (on File System) at this location C:\Mine\csharp\command. Here I created two folders inside command folder. source and build.
Now from any Text Editor create a small sample program (I am using Notepad++), as below, save it as WinFormExample.cs under source folder :
using System;
using System.Drawing;
using System.Windows.Forms;
namespace CSharpGUI {
public class WinFormExample : Form {
private Button button;
public WinFormExample() {
DisplayGUI();
}
private void DisplayGUI() {
this.Name = "WinForm Example";
this.Text = "WinForm Example";
this.Size = new Size(150, 150);
this.StartPosition = FormStartPosition.CenterScreen;
button = new Button();
button.Name = "button";
button.Text = "Click Me!";
button.Size = new Size(this.Width - 50, this.Height - 100);
button.Location = new Point(
(this.Width - button.Width) / 3 ,
(this.Height - button.Height) / 3);
button.Click += new System.EventHandler(this.MyButtonClick);
this.Controls.Add(button);
}
private void MyButtonClick(object source, EventArgs e) {
MessageBox.Show("My First WinForm Application");
}
public static void Main(String[] args) {
Application.Run(new WinFormExample());
}
}
}
Now type csc /out:build\WinFormExample.exe source\WinFormExample.cs (more info is given at the end, for compiler options)and press ENTER to compile as shown below :
Now simply run it using .\build\WinExample, as shown below :
Now your simple GUI Application is up and running :-)
Do let me know, I can explain the same thingy regarding Java as well, if need be :-)
More info regarding Compiler Options can be found on C# Compiler Options Listed Alphabetically
There is nothing magic in WinForms drag & drop. You can reference the same classes from System.Windows.Forms. If you are going to roll your own, I would suggest looking at the Model View Presenter pattern.
Here is a nice article comparing Java Swing and WinForms:
Related
I am writing the functionality of a deprecated VS Addin into a Package extension for VS 2015.
In the package extension there is a tool window with a toolbar containing some buttons which execute commands. Amongst these, there is a 'Save All' button, which should not only save the files of the solution to the local disk, but also save the files back to the database to which the user is connected. This works fine at present. However, the user will probably click on the standard Visual Studio 'Save All' button, and expect the files to be written to the database as well. So I need to intercept the standard 'Save All' command and add my method that handles the saving of the files to the database.
I managed to do this, but it is just not as neat as I think it should be. I'm not knowledgeable regarding events and delegates. I read up about it, and then I don't use it often enough, and then I forget what I read and so on.
So the functionality for the 'Save All' toolbar button in the package extension is found as follows in the Package.cs file. In the Initialize method:
protected override void Initialize()
{
OleMenuCommandService mcs = GetService(typeof(IMenuCommandService)) as OleMenuCommandService;
if (null != mcs)
{
CommandID saveAllCommandID = new CommandID(new Guid(Guids.guidConnectCommandPackageCmdSet), (int)PkgCmdIDList.cmdidSaveAllCommand);
command = new OleMenuCommand(new EventHandler(SaveAllCommandCallback), saveAllCommandID);
command.BeforeQueryStatus += BeforeQueryStatusCallback;
mcs.AddCommand(command);
}
visualStudioInstance = (DTE2)this.ServiceProvider.GetService(typeof(DTE));
CreateEventHandlers(visualStudioInstance);
}
and here is the SaveAllCommandCallback:
private void SaveAllCommandCallback(object caller, EventArgs args)
{
SaveAllDocuments();
OutputCommandString("In SaveAll Command Callback");
}
SaveAllDocuments is the method responsible for saving the files to the database. I don't think it is necessary to post that.
My attempt to intercept the standard Visual Studio "Save All" button's command is as follows:
In the Initialize method above, there is a method CreateEventHandlers:
private void CreateEventHandlers(DTE2 visualStudioInstance)
{
Events2 evs = visualStudioInstance.Events as Events2;
Commands cmds = visualStudioInstance.Commands;
Command cmdobj = cmds.Item("File.SaveAll", 0);
saveAllCommandEvents = evs.get_CommandEvents(cmdobj.Guid, cmdobj.ID);
saveAllCommandEvents.BeforeExecute += new _dispCommandEvents_BeforeExecuteEventHandler(m_SaveAllCommand_BeforeExecute);
}
And then here is m_SaveAllCommand_BeforeExecute:
private void m_SaveAllCommand_BeforeExecute(string Guid, int ID, object CustomIn, object CustomOut, ref bool CancelDefault)
{
SaveAllDocuments();
CancelDefault = true;
}
As you can see, it calls SaveAllDocuments and sets CancelDefault to true, which I think signals to the caller that it has interfered with the command and not only been a listener. Should it be set to true?
Anyways, my main question is, how do I link saveAllCommandEvents.BeforeExecute to the SaveAllCommandCallback? I think it would be better to have SaveAllDocuments called from only one place, in SaveAllCommandCallback, but I don't know how to link the callback to the event of the standard Visual Studio "Save All" button.
I guess this should be simple if one is familiar with events and delegates, but I'm not. I just have a feeling that what I'm currently doing could be improved.
I recommend not to use CancelDefault = true; in m_SaveAllCommand_BeforeExecute and just call SaveTheFilesBackToTheDatabase() from it.
I am working from the sample project here: http://www.codeproject.com/Articles/8086/Extending-the-save-file-dialog-class-in-NET
I have hidden the address/location bar at the top and made other modifications but I can't for the life of me manage to disable the button that lets you go up to the parent folder. Ist is in the ToolbarWindow32 class which is the problem. This is what I have at the moment but it is not working:
int parentFolderWindow = GetDlgItem(parent, 0x440);
//Doesn't work
//ShowWindow((IntPtr)parentFolderWindow, SW_HIDE);
//40961 gathered from Spy++ watching messages when clicking on the control
// doesn't work
//SendMessage(parentFolderWindow, TB_ENABLEBUTTON, 40961, 0);
// doesn't work
//SendMessage(parentFolderWindow, TB_SETSTATE, 40961, 0);
//Comes back as '{static}', am I working with the wrong control maybe?
GetClassName((IntPtr)parentFolderWindow, lpClassName, (int)nLength);
Alternatively, if they do use the parent folder button and go where I don't want them to, I'm able to look at the new directory they land in, is there a way I can force the navigation to go back?
Edit: Added screenshot
//Comes back as '{static}', am I working with the wrong control maybe?
You know you are using the wrong control, you expected to see "ToolbarWindow32" back. A very significant problem, a common one for Codeproject.com code, is that this code cannot work anymore as posted. Windows has changed too much since 2004. Vista was the first version since then that added a completely new set of shell dialogs, they are based on IFileDialog. Much improved over its predecessor, in particular customizing the dialog is a lot cleaner through the IFileDialogCustomize interface. Not actually what you want to do, and customizations do not include tinkering with the navigation bar.
The IFileDialogEvents interface delivers events, the one you are looking for is the OnFolderChanging event. Designed to stop the user from navigating away from the current folder, the thing you really want to do.
While this looks good on paper, I should caution you about actually trying to use these interfaces. A common problem with anything related to the Windows shell is that they only made it easy to use from C++. The COM interfaces are the "unfriendly" kind, interfaces based on IUnknown without a type library you can use the easily add a reference to your C# or VB.NET project. Microsoft published the "Vista bridge" to make these interfaces usable from C# as well, it looks like this. Yes, yuck. Double yuck when you discover you have to do this twice, this only works on later Windows versions and there's a strong hint that you are trying to do this on XP (judging from the control ID you found).
This is simply not something you want to have to support. Since the alternative is so simple, use the supported .NET FileOk event instead. A Winforms example:
private void SaveButton_Click(object sender, EventArgs e) {
string requiredDir = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
using (var dlg = new SaveFileDialog()) {
dlg.InitialDirectory = requiredDir;
dlg.FileOk += (s, cea) => {
string selectedDir = System.IO.Path.GetDirectoryName(dlg.FileName);
if (string.Compare(requiredDir, selectedDir, StringComparison.OrdinalIgnoreCase) != 0) {
string msg = string.Format("Sorry, you cannot save to this directory.\r\nPlease select '{0}' instead", requiredDir);
MessageBox.Show(msg, "Invalid folder selection");
cea.Cancel = true;
}
};
if (dlg.ShowDialog() == DialogResult.OK) {
// etc...
}
}
}
I don't this is going to work. Even if you disable the button they can type ..\ and click save and it will take them up one level. You can't exactly disable the file name text box and maintain the functionality of the dialog.
You'd be better off either using the FolderBrowserDialog and setting it's RootFolder property and asking the user to type the filename in or auto generating it.
If the folder you are wanting to restrict the users to isn't an Environment.SpecialFolder Then you'll need to do some work to make the call to SHBrowseForFolder Manually using ILCreateFromPath to get a PIDLIST_ABSOLUTE for your path to pass to the BROWSEINFO.pidlRoot
You can reflect FolderBrowserDialog.RunDialog to see how to make that call.
Since you want such custom behaviors instead of developing low level code (that is likely yo break in the next versions of windows) you can try to develop your file picker form.
Basically it is a simple treeview + list view. Microsoft has a walk-through .
It will take you half a day but once you have your custom form you can define all behaviors you need without tricks and limits.
I've found a very nice tutorial and i am trying to understand something that is not in this tutorial (because the tut itself works fine)
http://www.codeproject.com/Articles/9163/File-Rating-a-practical-example-of-shell-extension
When you look at applications like WinRar, TortoiseSVN, Antivirus-apps and many more, there is an icon next to the Shell Extension Item.
I would like to know how this is done. (Programmatically with C#)
Adding a separator works, adding a submenu works and click+action also works, but i'm struggling with the icon. This cannot be so hard. Can somebody help me?
And please don't say that Microsoft doesn't longer support this in .NET 4.0, because it is not guaranteed and therefore they don't supply samplecode. If all those other apps can do it, then it is possible.
Please supply me some sample code, some tutorials or maybe even a working piece of code.
Please have a look at the following article, it uses .NET 4.0 it to create Windows Shell Extensions using the SharpShell nuget package.
NET Shell Extensions - Shell Context Menus
Using this library, you can set the image directly while creating the contextmenustrip as shown below
protected override ContextMenuStrip CreateMenu()
{
// Create the menu strip.
var menu = new ContextMenuStrip();
// Create a 'count lines' item.
var itemCountLines = new ToolStripMenuItem
{
Text = "Count Lines...",
Image = Properties.Resources.CountLines
};
// When we click, we'll count the lines.
itemCountLines.Click += (sender, args) => CountLines();
// Add the item to the context menu.
menu.Items.Add(itemCountLines);
// Return the menu.
return menu;
}
You only have to add to the following registry key: HKEY_LOCAL_MACHINE\SOFTWARE\Classes*\shellex\ContextMenuHandlers
and here is the code:
string TimeStamp = DateTime.Now.ToString("dd-MM-yyyy");
string key = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes\\*\\shellex\\ContextMenuHandlers\\Winrar";
string valueName = "MyWinrar";
Microsoft.Win32.Registry.SetValue(key, valueName, HERE WHAT YOU WANT TO START, Microsoft.Win32.RegistryValueKind.String);
i hope it works for you!
All the apps you listed use COM and unmanaged code to create overlay icon handlers. There is even a special project TortoiseOverlays that provides a common library for drawing icons for TortoiceCSV, TortoiseSVN and TortoiseGIT. You can take a look at it's source code to find out how it is done. If you want to draw similar icons, you should probably just reuse it.
Using .Net for this type of extensions is not recommended, because when multiple extensions, built against different .Net versions would attempt to load in explorer process, they will crash the explorer.
I develop a WPF4 application and in my app I need to let the user select a folder where the application will store something (files, generated reports etc.).
My requirements:
Ability to see the standard folder tree
Ability to select a folder
WPF look & feel, this dialog must look like part of a modern application designed for Windows Vista/7 and not Windows 2000 or even Win9x.
As I understand, until 2010 (.Net 4.0) there won't be a standard folder dialog, but maybe there are some changes in version 4.0?
Or the only thing I can do, is to use an old-school WinForms dialog? If it's the only way to do what I need, how can I make it looking closer to Vista/7 style and not Win9x?
Windows Presentation Foundation 4.5 Cookbook by Pavel Yosifovich on page 155 in the section on "Using the common dialog boxes" says:
"What about folder selection (instead of files)? The WPF
OpenFileDialog does not support that. One solution is to use Windows
Forms' FolderBrowseDialog class. Another good solution is to use the
Windows API Code Pack described shortly."
I downloaded the API Code Pack from Windows® API Code Pack for Microsoft® .NET Framework Windows API Code Pack: Where is it?, then added references to Microsoft.WindowsAPICodePack.dll and Microsoft.WindowsAPICodePack.Shell.dll to my WPF 4.5 project.
Example:
using Microsoft.WindowsAPICodePack.Dialogs;
var dlg = new CommonOpenFileDialog();
dlg.Title = "My Title";
dlg.IsFolderPicker = true;
dlg.InitialDirectory = currentDirectory;
dlg.AddToMostRecentlyUsedList = false;
dlg.AllowNonFileSystemItems = false;
dlg.DefaultDirectory = currentDirectory;
dlg.EnsureFileExists = true;
dlg.EnsurePathExists = true;
dlg.EnsureReadOnly = false;
dlg.EnsureValidNames = true;
dlg.Multiselect = false;
dlg.ShowPlacesList = true;
if (dlg.ShowDialog() == CommonFileDialogResult.Ok)
{
var folder = dlg.FileName;
// Do something with selected folder string
}
I wrote about it on my blog a long time ago, WPF's support for common file dialogs is really bad (or at least is was in 3.5 I didn't check in version 4), but it's easy to work around it.
You need to add the correct manifest to your application, that will give you a modern style message boxes and folder browser (WinForms, FolderBrowserDialog) but not WPF file open/save dialogs, this is described in those 3 posts (if you don't care about the explanation and only want the solution go directly to the 3rd):
Why am I Getting Old Style File Dialogs and Message Boxes with WPF
Will Setting a Manifest Solve My WPF Message Box Style Problems?
The Application Manifest Needed for XP and Vista Style File Dialogs and Message Boxes with WPF
Fortunately, the open/save dialogs are very thin wrappers around the Win32 API that is easy to call with the right flags to get the Vista/7 style (after setting the manifest)
Vista style open and save dialogs with WPF (without using the Vista bridge sample)
Add The Windows API Code Pack-Shell to your project
using Microsoft.WindowsAPICodePack.Dialogs;
...
var dialog = new CommonOpenFileDialog();
dialog.IsFolderPicker = true;
CommonFileDialogResult result = dialog.ShowDialog();
If you don't want to use Windows Forms nor edit manifest files, I came up with a very simple hack using WPF's SaveAs dialog for actually selecting a directory.
No using directive needed, you may simply copy-paste the code below !
It should still be very user-friendly and most people will never notice.
The idea comes from the fact that we can change the title of that dialog, hide files, and work around the resulting filename quite easily.
It is a big hack for sure, but maybe it will do the job just fine for your usage...
In this example I have a textbox object to contain the resulting path, but you may remove the related lines and use a return value if you wish...
// Create a "Save As" dialog for selecting a directory (HACK)
var dialog = new Microsoft.Win32.SaveFileDialog();
dialog.InitialDirectory = textbox.Text; // Use current value for initial dir
dialog.Title = "Select a Directory"; // instead of default "Save As"
dialog.Filter = "Directory|*.this.directory"; // Prevents displaying files
dialog.FileName = "select"; // Filename will then be "select.this.directory"
if (dialog.ShowDialog() == true) {
string path = dialog.FileName;
// Remove fake filename from resulting path
path = path.Replace("\\select.this.directory", "");
path = path.Replace(".this.directory", "");
// If user has changed the filename, create the new directory
if (!System.IO.Directory.Exists(path)) {
System.IO.Directory.CreateDirectory(path);
}
// Our final value is in path
textbox.Text = path;
}
The only issues with this hack are :
Acknowledge button still says "Save" instead of something like "Select directory", but in a case like mines I "Save" the directory selection so it still works...
Input field still says "File name" instead of "Directory name", but we can say that a directory is a type of file...
There is still a "Save as type" dropdown, but its value says "Directory (*.this.directory)", and the user cannot change it for something else, works for me...
Most people won't notice these, although I would definitely prefer using an official WPF way if microsoft would get their heads out of their asses, but until they do, that's my temporary fix.
The FolderBrowserDialog class from System.Windows.Forms is the recommended way to display a dialog that allows a user to select a folder.
Until recently, the appearance and behaviour of this dialog was not in keeping with the other file system dialogs, which is one of the reasons why people were reluctant to use it.
The good news is that FolderBrowserDialog was "modernized" in NET Core 3.0, so is now a viable option for those writing either Windows Forms or WPF apps targeting that version or later.
In .NET Core 3.0, Windows Forms users [sic] a newer COM-based control that was introduced in Windows Vista:
To reference System.Windows.Forms in a NET Core WPF app, it is necessary to edit the project file and add the following line:
<UseWindowsForms>true</UseWindowsForms>
This can be placed directly after the existing <UseWPF> element.
Then it's just a case of using the dialog:
using System;
using System.Windows.Forms;
...
using var dialog = new FolderBrowserDialog
{
Description = "Time to select a folder",
UseDescriptionForTitle = true,
SelectedPath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory)
+ Path.DirectorySeparatorChar,
ShowNewFolderButton = true
};
if (dialog.ShowDialog() == DialogResult.OK)
{
...
}
FolderBrowserDialog has a RootFolder property that supposedly "sets the root folder where the browsing starts from" but whatever I set this to it didn't make any difference; SelectedPath seemed to be the better property to use for this purpose, however the trailing backslash is required.
Also, the ShowNewFolderButton property seems to be ignored as well, the button is always shown regardless.
Microsoft.Win32.OpenFileDialog is the standard dialog that any application on Windows uses. Your user won't be surprised by its appearance when you use WPF in .NET 4.0
The dialog was altered in Vista. WPF in .NET 3.0 and 3.5 still used the legacy dialog but that was fixed in .NET 4.0. I can only guess that you started this thread because you are seeing that old dialog. Which probably means you're actually running a program that is targeting 3.5. Yes, the Winforms wrapper did get the upgrade and shows the Vista version. System.Windows.Forms.OpenFileDialog class, you'll need to add a reference to System.Windows.Forms.
MVVM + WinForms FolderBrowserDialog as behavior
public class FolderDialogBehavior : Behavior<Button>
{
public string SetterName { get; set; }
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.Click += OnClick;
}
protected override void OnDetaching()
{
AssociatedObject.Click -= OnClick;
}
private void OnClick(object sender, RoutedEventArgs e)
{
var dialog = new FolderBrowserDialog();
var result = dialog.ShowDialog();
if (result == DialogResult.OK && AssociatedObject.DataContext != null)
{
var propertyInfo = AssociatedObject.DataContext.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public)
.Where(p => p.CanRead && p.CanWrite)
.Where(p => p.Name.Equals(SetterName))
.First();
propertyInfo.SetValue(AssociatedObject.DataContext, dialog.SelectedPath, null);
}
}
}
Usage
<Button Grid.Column="3" Content="...">
<Interactivity:Interaction.Behaviors>
<Behavior:FolderDialogBehavior SetterName="SomeFolderPathPropertyName"/>
</Interactivity:Interaction.Behaviors>
</Button>
Blogpost: http://kostylizm.blogspot.ru/2014/03/wpf-mvvm-and-winforms-folder-dialog-how.html
Based on Oyun's answer, it's better to use a dependency property for the FolderName. This allows (for example) binding to sub-properties, which doesn't work in the original. Also, in my adjusted version, the dialog shows selects the initial folder.
Usage in XAML:
<Button Content="...">
<i:Interaction.Behaviors>
<Behavior:FolderDialogBehavior FolderName="{Binding FolderPathPropertyName, Mode=TwoWay}"/>
</i:Interaction.Behaviors>
</Button>
Code:
using System.Windows;
using System.Windows.Forms;
using System.Windows.Interactivity;
using Button = System.Windows.Controls.Button;
public class FolderDialogBehavior : Behavior<Button>
{
#region Attached Behavior wiring
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.Click += OnClick;
}
protected override void OnDetaching()
{
AssociatedObject.Click -= OnClick;
base.OnDetaching();
}
#endregion
#region FolderName Dependency Property
public static readonly DependencyProperty FolderName =
DependencyProperty.RegisterAttached("FolderName",
typeof(string), typeof(FolderDialogBehavior));
public static string GetFolderName(DependencyObject obj)
{
return (string)obj.GetValue(FolderName);
}
public static void SetFolderName(DependencyObject obj, string value)
{
obj.SetValue(FolderName, value);
}
#endregion
private void OnClick(object sender, RoutedEventArgs e)
{
var dialog = new FolderBrowserDialog();
var currentPath = GetValue(FolderName) as string;
dialog.SelectedPath = currentPath;
var result = dialog.ShowDialog();
if (result == DialogResult.OK)
{
SetValue(FolderName, dialog.SelectedPath);
}
}
}
The Ookii Dialogs for WPF has a VistaFolderBrowserDialog class that provides a complete implementation of a folder browser dialog for WPF.
https://github.com/augustoproiete/ookii-dialogs-wpf
There's also a version that works with Windows Forms.
Only such dialog is FileDialog. Its part of WinForms, but its actually only wrapper around WinAPI standard OS file dialog. And I don't think it is ugly, its actually part of OS, so it looks like OS it is run on.
Other way, there is nothing to help you with. You either need to look for 3rd party implementation, either free (and I don't think there are any good) or paid.
Just to say one thing, WindowsAPICodePack can not open CommonOpenFileDialog on Windows 7 6.1.7600.
A comment on the original question from C. Augusto Proiete suggested Ookii dialogs (https://github.com/ookii-dialogs/ookii-dialogs-wpf). That's what I ended up using in my situation. Here's how I used it in my app.
var dialog = new VistaFolderBrowserDialog()
{
Description = "Select Folder",
RootFolder = Environment.SpecialFolder.Desktop,
ShowNewFolderButton = true,
UseDescriptionForTitle = true
};
var result = dialog.ShowDialog();
if (result.HasValue && result.Value)
{
_mySelectedFolder = dialog.SelectedPath;
}
I have a C# application that creates shortcuts to launch other programs with specific arguments and initial directories. I would like the user to be able to drag a shortcut from the Windows form and drop it anywhere relevant like the desktop, the start menu, and so on but I don't really know how to handle that, could anyone point me in the right direction?
I have seen a few samples using PInvoke and IShellLink like this one, or read answers on SO like here, which already help create shortcuts and save them in a .lnk file. I assume I have to hand over data in a DoDragDrop() call when the user initiates a drag operation, for example by handling a MouseDown signal. That's as far as I got, I suppose I need to know exactly which type the target is expecting to accept the drop, and how to serialize the shortcut, but couldn't find any information on that part.
Perhaps another option would be to get the location of the drop, and manage that from my application, but there again I'm a bit clueless as how to do that.
The framework version is currently 3.5, and I'm only considering Windows platforms.
Thanks in advance for your help!
Update/Solution:
Using the ShellLink code mentioned above to create a temporary shortcut file, I simply used DataObject for the drag and drop, like in the following example:
private void picShortcut_MouseDown(object sender, MouseEventArgs e)
{
ShellLink link = new ShellLink();
// Creates the shortcut:
link.Target = txtTarget.Text;
link.Arguments = txtArguments.Text;
link.Description = txtDescription.Text;
link.IconPath = txtIconFile.Text;
link.IconIndex = (txtIconIndex.Text.Length > 0 ?
System.Int32.Parse(txtIconIndex.Text) : 0);
link.Save("tmp.lnk");
// Starts the drag-and-drop operation:
DataObject shortcut = new DataObject();
StringCollection files = new StringCollection();
files.Add(Path.GetFullPath("tmp.lnk"));
shortcut.SetFileDropList(files);
picShortcut.DoDragDrop(shortcut, DragDropEffects.Copy);
}
Quite complicated if you consider the PInvoke code (not shown here), and I still need to create this temporary file with the target name. If anyone knows a... erm, shortcut, it's welcome! Perhaps by porting the code for which John Knoeller gave a link (thanks!).
Raymond Chen did a whole article on this very topic on his blog check out dragging a virtual file
I answered a question sort of similar to this on a previous thread. This might be a starting point for you.
Drag and Drop link