WPF dealing with files in a listBox - c#

I intend to create a .mp4 Listbox from which I can play an .mp4 of my choice.
I've already created the .mp4 player(by drag&drop) and I'm dealing with trouble with how to deal with the listBox.
private void button1_Click(object sender, RoutedEventArgs e)
{
var dialog = new System.Windows.Forms.FolderBrowserDialog();
System.Windows.Forms.DialogResult result = dialog.ShowDialog();
try
{
DirectoryInfo dr = new DirectoryInfo(dialog.SelectedPath.ToString());
if (result == FORMS.DialogResult.OK)
{
foreach (FileInfo f in dr.GetFiles())
{
listBox1.Items.Add(f);
}
}
}
catch { }
}
This only enables me to get all the .mp4 files(from selected folder) to be shown in the listBox,
How do I manage to drag objects from the listBox into the .mp4 player(which is already drag and drop enabled).

You can do it using the DragDrop.DoDragDrop method.
Example:
<ListBox SelectionChanged="Selector_OnSelectionChanged">
<ListBoxItem>X</ListBoxItem>
<ListBoxItem>Y</ListBoxItem>
<ListBoxItem>Z</ListBoxItem>
</ListBox>
And in code
private void Selector_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
ListBox listbox = sender as ListBox;
DragDrop.DoDragDrop(listbox, listbox.SelectedItem, DragDropEffects.None);
}
Could be that in your mp4 player you'll need to implement more than just enable drag&Drop (like extract dragged item and play it ...)
You can find more information about on MSDN Drag and Drop Overview page.
Hope this helps

:) Thanks alot, that really helps! You were right about the .mp4 player, he does need to identify the drag onto him but I just couldn't figure out how. I did manage to write the code to play an .mp4 by dragging an .mp4 directly from your computer (desktop for example) and here's the code for that:
private void Grid_Drop(object sender, DragEventArgs e)
{
string filename = (string)((DataObject)e.Data).GetFileDropList()[0];
mediaElement1.Source =new Uri(filename);
mediaElement1.LoadedBehavior = MediaState.Manual;
mediaElement1.UnloadedBehavior = MediaState.Manual;
mediaElement1.Volume = (double)slider_vol.Value;
mediaElement1.Play();
}
There are other add-ons to that code but they don't really matter.
What function from Drag and Drop should I use on the "Play" button for the player? and how do I get the filename to actually handle that file? Thanks!

Related

Dragging a file from a TreeNode to the desktop or Windows Explorer?

I am attempting to drag a file represented by a TreeView node onto the desktop, Windows Explorer, or any other applications that allow files to be dropped onto them. I've written the code below based on various Internet examples I've found and I'm running it as administrator. It does allow me to drag as long as I remain in the TreeView control that contains the nodes, displaying the Copy icon with the cursor as it moves. However, when I drag it off the control to the desktop or Windows Explorer for example, the icon turns into the red circle with a slash across it and nothing gets dropped. I've ensured that the dragged file actually does exist.
private void treeView_Files_ItemDrag(object sender, ItemDragEventArgs e)
{
DoDragDrop(e.Item, DragDropEffects.Copy);
}
private void treeView_Files_DragDrop(object sender, DragEventArgs e)
{
TreeNode NewNode;
if (e.Data.GetDataPresent("System.Windows.Forms.TreeNode", false))
{
Point pt = ((TreeView)sender).PointToClient(new Point(e.X, e.Y));
TreeNode DestinationNode = ((TreeView)sender).GetNodeAt(pt);
NewNode = (TreeNode)e.Data.GetData("System.Windows.Forms.TreeNode");
string[] files = new string[] { "C:\\temp\\TestFile.pdf" };
DataObject dataObject = new DataObject(DataFormats.FileDrop, files);
DoDragDrop(dataObject, DragDropEffects.Copy);
}
}
I was unable to figure out why my original code above would not display the Copy icon on the cursor unless it was within the TreeView control itself and, hence, would not let me drop the desired file. However, I was able to come up with a solution that does display the icon and will drop on any application capable of accepting a dropped file. I simply abandoned the use of the ItemDrag and DragDrop events entirely and used the MouseDown event instead as shown below. As in my original code I'm using a test file instead of the file represented by the node, but extracting the real file path from the node is trivial. Of course some additional simple code is necessary to determine if the coordinates are actually on a node:
private void treeView_Files_MouseDown(object sender, MouseEventArgs e)
{
TreeNode node = treeView_Files.GetNodeAt(e.X, e.Y);
string[] files = new string[] { "C:\\temp\\TestFile.pdf" };
DataObject dataObject = new DataObject(DataFormats.FileDrop, files);
DoDragDrop(dataObject, DragDropEffects.Copy);
}
Try constructing the DataObject and performing the DoDragDrop() operation inside the ItemDrag function, instead of the DragDrop function:
private void treeView_Files_ItemDrag(object sender, ItemDragEventArgs e)
{
string[] files = new string[] { "C:\\temp\\TestFile.pdf"};
DataObject dataObject = new DataObject(DataFormats.FileDrop, files);
DoDragDrop(dataObject, DragDropEffects.Copy);
}
The e.Item parameter (which is the TreeView item) is not really the object that you want to pass to Explorer, so you shouldn't be putting it into the DoDragDrop call.
On a side note, I spent a long time researching how it's possible to get the "destination" folder onto which the item was dropped. My solution involves roughly the following:
Create a FileSystemWatcher and make it send events when new files are created.
Give it a Filter that matches the file name that you're dropping.
When the file is dropped (i.e. when it's created in the destination folder), you'll receive an event via the watcher.
Something like this:
private void CreateWatcher()
{
var watcher = new FileSystemWatcher();
watcher.Filter = "TestFile.pdf";
watcher.NotifyFilter = NotifyFilters.FileName;
watcher.Created += new FileSystemEventHandler(OnWatcherFileCreated);
watcher.IncludeSubdirectories = true;
watcher.Path = "C:\\";
watcher.EnableRaisingEvents = true;
}
private void OnWatcherFileCreated(object sender, FileSystemEventArgs e)
{
// Note: this happens in a separate non-UI thread.
Console.WriteLine("Dropped onto: " + e.FullPath);
}

Drag multiple files

I have a ListBox with a list of filepaths, which has the property SelectionMode set to MultiExtended. Thus, I can select many items from this list.
Now, I want to Drag and Drop files starting from those paths in the destination folder where I drop them.
My code:
private void Form1_Load(object sender, EventArgs e)
{
// populate the FileList
// i.e. FileList.Items.Add("d:/Samples/file-00" + i + ".wav");
this.FileList.MouseDown += new MouseEventHandler(FileList_MouseDown);
this.FileList.DragOver += new DragEventHandler(FileList_DragOver);
}
void FileList_DragOver(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Copy;
}
void FileList_MouseDown(object sender, MouseEventArgs e)
{
List<string> filesToDrag = new List<string>();
foreach (var item in FileList.SelectedItems)
{
filesToDrag.Add(item.ToString().Trim());
}
this.FileList.DoDragDrop(new DataObject(DataFormats.FileDrop,
filesToDrag.ToArray()), DragDropEffects.Copy);
}
it works perfect if I select and drop 1 single line/file from the ListBox to the destination folder.
Instead, if I do a multiple selection and I try to drag and drop, it can just select that one line where I start to drag. Seems that MouseDown prevent this?
How would you fix the problem?
Doing this with a ListBox seems to be ridiculously hard. Actually I haven't found a solution at all..
Use a ListView instead! It is easy as pie, using the ItemDrag event and is a much better control anyway.. I can't count how often I had to change from a 'cheap' ListBox to ListView because I needed this or that 'little' extra..
Here is your code moved to a ItemDrag:
private void listView1_ItemDrag(object sender, ItemDragEventArgs e)
{
List<string> filesToDrag = new List<string>();
foreach (var item in listView1.SelectedItems)
{
filesToDrag.Add(item.ToString().Trim());
}
this.listView1.DoDragDrop(new DataObject(DataFormats.FileDrop,
filesToDrag.ToArray()), DragDropEffects.Copy);
}
Note that this only solves the problem of the MouseDown changing the selection. It is in itself not a guarantuee that the actual copying will work.
I found this interesting article that proposes a solution. Maybe you don't need it, as you have said that you got copying one file already working..
Yeah...I don't think there's a good way around that problem. When you click again to initiate the drag it will toggle that item. We don't know that the user actually wants to do a drag until the mouse is held down and moved.
One potential solution is to initiate the drag/drop from something else, just somehow make it really clear that is what the user should drag. Here I'm using a Label instead of the ListBox:
void label1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
List<string> filesToDrag = new List<string>();
foreach (var item in FileList.SelectedItems)
{
filesToDrag.Add(item.ToString().Trim());
}
if (filesToDrag.Count > 0)
{
this.FileList.DoDragDrop(new DataObject(DataFormats.FileDrop,
filesToDrag.ToArray()), DragDropEffects.Copy);
}
else
{
MessageBox.Show("Select Files First!");
}
}
}
You have to be picky about the mouse down and mouse move activities. When it is within the graphics rectangle of your listbox, you'll want normal behavior. When it is outside the bounds of this rectangle, you'll want drag/drop functionality. You can try the pseudo code below:
MouseDown(sender, e)
{
var x = <your sender as control>.ItemFromPoint(.....)
this.mouseLocation = x == null ? x : e.Location;
}
MouseMove(sender, e)
{
if control rectangle doesn't contain the current location then
<your sender as control>.Capture = false
DoDragDrop
}

Get SOurce of a drag&drop

I have an WPF-Datagrid where I can drop an element. This is a Textelement dropped from an .txt file (open for example with notepad++). Is there any possibility to get information about the .txt file on my Drop-Event ?
Edit:
void OnDragDrop(object sender, DragEventArgs e)
{
String text = e.Data.GetData(DataFormats.Text, true);
}
Here I can get the Text of my drop element, but I found no solution to get the source file, where the drag get started.
ok here you go:
You have to do three things to enable drag'n drop in WPF:
Tell the element to support drag'n drop
Setup a DragOver Event
Setup a Drop Event
ok, let's first look at the XAML:
<DataGrid AllowDrop="True"
DragOver="DataGrid_DragOver"
Drop="DataGrid_Drop"/>
And the event handler code:
private void DataGrid_DragOver(object sender, DragEventArgs e)
{
// check if the element dragged over is one or more files
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
// if so, show a link cursor
e.Effects = DragDropEffects.Link;
}
else
{
// otherwise show a "block" cursor
e.Effects = DragDropEffects.None;
}
// IMPORTANT: mark the event as "handled by us", to apply the drag effects
e.Handled = true;
}
private void DataGrid_Drop(object sender, DragEventArgs e)
{
// Check if the data dropped is one or more files
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
// get the file pathes from the data object
string[] filePaths = (e.Data.GetData(DataFormats.FileDrop) as string[]);
// do something with the pathes
/* ... */
}
}
For more information see the MSDN documentation.
No.
Think of Drag & Drop the same way as Cut & Paste -- typically only the "data" is being dragged over during the event, and no additional metadata about its source.
One exception to this, is when dragging text from a web page. DataFormats.Html will include the SourceURL that the text came from.

How can I make a scrollabe image list in C# Windows Form?

I need to create thumbnails list of pictures located on web.
I would like also to add CheckBox to make thumbnails choose able.
I'm trying to load pictures from urls to ListBox
// from form design file:
System.Windows.Forms.ListBox listBoxPictures;
// from main file
foreach (Photo albumPhoto in album.Photos)
{
PictureBox albumsImg = new PictureBox();
albumsImg.LoadAsync(albumPhoto.URL); // URL is string
CheckBox selectedPhotoCheckBox = new CheckBox();
listBoxPictures.Items.Add(albumsImg);
listBoxPictures.Items.Add(selectedPhotoCheckBox);
}
It doesn't work, there are no images appear in ListBox.
What am I doing wrong?
How can I make a scrollabe image list in C# Windows Form?
what is wrong is that you have to wait load completed of picture
private void button1_Click(object sender, EventArgs e)
{
//make your loop here
pictureBox1.WaitOnLoad = false;
pictureBox1.LoadCompleted += new AsyncCompletedEventHandler(pictureBox1_LoadCompleted);
pictureBox1.LoadAsync(albumPhoto.URL);
}
void pictureBox1_LoadCompleted(object sender, AsyncCompletedEventArgs e)
{
//now your picture is loaded, add to list view
CheckBox selectedPhotoCheckBox = new CheckBox();
listBoxPictures.Items.Add(albumsImg);
listBoxPictures.Items.Add(selectedPhotoCheckBox);
}

Cannot Drag from Explorer onto ListView

I have seen this everywhere and tried all the solutions and am not seeming to get what I want. I want to be able to drop files from explorer onto a ListView and then be able to sort them through drag and drop. I am have this simple code that gets the drag/drop from explorer.
this.messageView.AllowDrop = true;
this.messageView.Location = new System.Drawing.Point(12, 52);
this.messageView.Name = "messageGrid";
this.messageView.Size = new System.Drawing.Size(121, 97);
this.messageView.TabIndex = 3;
this.messageView.UseCompatibleStateImageBehavior = false;
this.messageView.DragDrop += new System.Windows.Forms.DragEventHandler(this.Form1_DragDrop);
this.messageView.DragEnter += new System.Windows.Forms.DragEventHandler(this.Form1_DragEnter);
and the handlers
private void Form1_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent("FileGroupDescriptor"))
{
e.Effect = DragDropEffects.All;
}
}
private void Form1_DragDrop(object sender, DragEventArgs e)
{
messageView.Items.Add(e.Data.ToString());
}
This is bizarre, because of I change the messageView to a RichTextBox I have on my form, it works just fine. Are there additional steps that I have to do? When I attempt to drop onto the ListView, I get the circle with a line through it from Explorer. Any help would be appreciated. Thanks.
DragEnter and DragDrop events should be handled in the ListView, not in the Form.
About drag and drop: I do not remember the article name but I found a good example of it in codeproject.

Categories