Drag drop file in WPF not working - c#

I am using Mahapps for layout and AvalonDock for tabs and sub-windows layout. But unable to use drag drop functionality as the drag drop function never called. I have also set both(explorer and .exe) privileges to user according to link, but all in vain. Unable to get this thing work. Background of avalondock:DockingManager control is set to "#FF2D2D30". On dragging or dropping file from file explorer on dockingManager, nothing happens.
<avalonDock:DockingManager AllowDrop="True" x:Name="dockingManager" DockPanel.Dock="Right" Theme="{Binding AvalonDockTheme}" PreviewDragEnter="DragFilesEntered" PreviewDrop="FilesDropped" PreviewDragOver="DragFilesEntered">
<avalonDock:LayoutRoot>
<avalonDock:LayoutPanel Orientation="Horizontal">
<avalonDock:LayoutDocumentPaneGroup>
<avalonDock:LayoutDocumentPane x:Name="layoutdoc_tabContent">
</avalonDock:LayoutDocumentPane>
</avalonDock:LayoutDocumentPaneGroup>
</avalonDock:LayoutPanel>
</avalonDock:LayoutRoot>
</avalonDock:DockingManager>
Code Behind(C#) which i picked from some website
private void DragFilesEntered(object sender, DragEventArgs e)
{
MessageBox.Show("Hey");
bool isValidFile = false;
if (e.Data.GetDataPresent(DataFormats.FileDrop, true))
{
string[] filenames = (string[])e.Data.GetData(DataFormats.FileDrop, true);
foreach (string filename in filenames)
{
if (File.Exists(filename) == false)
{
isValidFile = false;
break;
}
FileInfo info = new FileInfo(filename);
if (!(info.Extension == ".bmp" || info.Extension == ".png" || info.Extension == ".jpg"))
{
isValidFile = false;
break;
}
}
}
if (isValidFile)
e.Effects = DragDropEffects.Move;
else
e.Effects = DragDropEffects.None;
}
private void FilesDropped(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop, true))
{
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
foreach(var file in files)
((MainViewModel)this.DataContext).CreateTab(layoutdoc_tabContent, file);
e.Handled = true;
}
}
EDIT:
<StackPanel PreviewDragEnter="DragFilesEntered" PreviewDrop="FilesDropped" PreviewDragOver="DragFilesEntered" AllowDrop="True" Width="100" Height="100" Orientation="Horizontal" Background="#FFDA1313">
</StackPanel>
Still not working.Unable to call Drag function.

Try to put the AllowDrop="True" and the associated handlers directly on the LayoutDocumentPane.
In general, in XAML, you have to put theses on the overred FrameworkElement by the cursor when dropping.

Related

Drag and Drop from Outlook into Winforms

When dragging items from Outlook email into a Winforms app (Control is a GalleryControl by DevExpress, the DragDrop event is not firing, even though i manually set 'DragDropEffects.Move` in the DragEnter event handler. (have confirmed that this is firing)
However DragDrop event does fire just when dragging normal files from windows explorer.
private async void gcImages_DragDrop(object sender, DragEventArgs e)
{
string[] fileNames = null;
if (e.Data.GetDataPresent(DataFormats.FileDrop, false) == true)
{
fileNames = (string[])e.Data.GetData(DataFormats.FileDrop);
}
else if (e.Data.GetDataPresent("FileGroupDescriptor"))
{
OutlookDataObject dataObject = new OutlookDataObject(e.Data);
string[] filenames = (string[])dataObject.GetData("FileGroupDescriptor");
}
// do stuff async with file names
}
private void gcImages_DragEnter(object sender, DragEventArgs e)
{
// This event fires, no matter what i drag onto it. (Files from explorer, attachments from Outlook etc)
// However even after setting the effect as per below, the cursor still shows the 'not allowed' symbol.
e.Effect = DragDropEffects.Move;
}
I have enabled AllowDrop = true on the control, and it works perfectly with Windows Explorer files, just not outlook files.
The strange thing is that the DragEnter event is firing, but the DragDrop event does not fire with Outlook attachments.
Ended up using this code, seemed to work fine.
//// Use Like This
private void gcImages_DragDrop(object sender, DragEventArgs e)
{
DragDropHelper.AcceptDroppedFile(e, AddAndSaveNewDocument);
}
private void AddAndSaveNewDocument(FileSystemInfo fileInfo)
{
}
////
public static class DragDropHelper
{
public static void AcceptDroppedFile(DragEventArgs e, Action<FileInfo> addAndSaveNewDocument)
{
string[] fileNames = null;
if (e.Data.GetDataPresent(DataFormats.FileDrop, false))
{
fileNames = (string[])e.Data.GetData(DataFormats.FileDrop);
}
else if (e.Data.GetDataPresent("FileGroupDescriptor"))
{
var dataObject = new OutlookDataObject(e.Data);
fileNames = (string[])dataObject.GetData("FileGroupDescriptor");
for (var i = 0; i < fileNames.Length; i++)
{
var itm = fileNames[i];
using var ms = dataObject.GetData("FileContents", i);
var tmpFileName = Path.Combine(Path.GetTempPath(), itm);
using (var file = new FileStream(tmpFileName, FileMode.Create, System.IO.FileAccess.Write))
{
byte[] bytes = new byte[ms.Length];
ms.Read(bytes, 0, (int)ms.Length);
file.Write(bytes, 0, bytes.Length);
ms.Close();
}
fileNames[i] = tmpFileName;
}
}
if (fileNames != null)
{
foreach (var fileName in fileNames)
{
var fileInfo = new FileInfo(fileName);
addAndSaveNewDocument(fileInfo);
if (fileName.Contains(Path.GetTempPath(), StringComparison.CurrentCultureIgnoreCase))
{
File.Delete(fileName);
}
}
}
}
}
Code here for OutlookDataObject class https://codeshare.io/G7747D

C# WPF FileInfo Media Source?

When I'm get .mp3 file without path but I couldn't play Uri got some errors. My codes;
private void listbox2_Drop(object sender, DragEventArgs e)
{
try
{
string[] a = (string[])(e.Data.GetData(DataFormats.FileDrop, false));
foreach (var names in a)
{
FileInfo fileInfo = new FileInfo(names);
if (fileInfo.Extension == ".MP3" ||fileInfo.Extension == ".mp3")
{
listbox2.Items.Add( fileInfo.Name);
}
}
}
catch (Exception)
{}
}
private void listbox2_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
object listboxİtems = listbox2.SelectedItem;
if (listboxİtems != null)
{
media2.Source = new Uri(listboxİtems.ToString(), UriKind.Relative); // I'm getting erors here
media2.Play();
}
}
he got error at media2.Source that listboxItems.ToString() string is unable to play
Just add the full FileInfo object to your Items.
Then you have the full object to build your Uri with FullPath or DirectoryName and Name.
Finally, define your ListBox.ItemTemplate to something that suits your needs (like a TextBlock bound to the Name property)
Here goes some of the requested code :
private void listbox2_Drop(object sender, DragEventArgs e)
{
try
{
string[] a = (string[])(e.Data.GetData(DataFormats.FileDrop, false));
foreach (var names in a)
{
FileInfo fileInfo = new FileInfo(names);
if (fileInfo.Extension == ".MP3" ||fileInfo.Extension == ".mp3")
{
listbox2.Items.Add(fileInfo); //store the full FileInfo in your Items, not just the Name property
}
}
}
catch (Exception)
{}
}
private void listbox2_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
FileInfo listboxItem = listbox2.SelectedItem as FileInfo; //cast the SelectedItem to the FileInfo type
if (listboxItem != null)
{
media2.Open(new Uri(listboxItem.FullPath, UriKind.RelativeOrAbsolute)); // if I remember well, Source is Read-Only, use Open instead
media2.Play();
}
}
And the suggested XAML for the ListBox :
<ListBox>
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

Windows Phone Refresh button not working

I have a Windows phone application which gets a list of photos URLs from a SQL database depending what it uploaded.
The issue i have is users can add their own photos to that list but it does not refresh the list on the page so i added a refresh to re run the code but it still does not run.
Well the code runs but does not update the list box.
//get/clean these strings
int parkID = 0;
string parkName = string.Empty;
public photos()
{
InitializeComponent();
BuildLocalizedApplicationBar();
}
private void ThemeParkPhotos_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
if (e.Error == null)
{
try
{
//No errors have been passed now need to take this file and parse it
//Its in XML format
XDocument xdox = XDocument.Parse(e.Result);
//need a list for them to be put in to
List<Photos> themeparkPhoto = new List<Photos>();
themeparkPhoto.Clear();
XNamespace ns = "http://schemas.datacontract.org/2004/07/WCFServiceWebRole1";
//Now need to get every element and add it to the list
foreach (XElement item in xdox.Descendants(ns + "Photos"))
{
Photos content = new Photos();
content.ID = Convert.ToInt32(item.Element(ns + "ID").Value);
content.PhotoURL = Convert.ToString(item.Element(ns + "PhotoURL").Value);
//content.ID = Convert.ToInt32(item.Element(ns + "id").Value);
//content.ThemeParkName = item.Element(ns + "name").Value.ToString();
themeparkPhoto.Add(content);
}
ThemeParkPhoto.ItemsSource = null;
ThemeParkPhoto.ItemsSource = themeparkPhoto.ToList();
//Delete all the stuff
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
else
{
//There an Error
}
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
//This is to get the data that was passed from the home screen to which song to use!
base.OnNavigatedTo(e);
if ((NavigationContext.QueryString["pID"] == string.Empty) || (NavigationContext.QueryString["pName"] == string.Empty))
{
//if not show message box.
MessageBox.Show("Empty Vaules have been sent, Please got back and try again");
}
else
{
parkID = Convert.ToInt32(NavigationContext.QueryString["pID"]);
parkName = NavigationContext.QueryString["pName"].ToString();
PageName.Text = parkName;
GetThemeParkPhotos();
}
}
public void GetThemeParkPhotos()
{
WebClient ThemeParkPhotos = new WebClient();
ThemeParkPhotos.DownloadStringCompleted += ThemeParkPhotos_DownloadStringCompleted;
ThemeParkPhotos.DownloadStringAsync(new Uri("HIDDEDURL/viewphotos?format=xml&themeparkid=" + parkID));
//MessageBox.Show("Test if this works"+parkID);
}
private void BuildLocalizedApplicationBar()
{
ApplicationBar = new ApplicationBar();
ApplicationBar.Mode = ApplicationBarMode.Default;
ApplicationBar.Opacity = 1.0;
ApplicationBar.IsVisible = true;
ApplicationBar.IsMenuEnabled = true;
ApplicationBarIconButton AddButton = new ApplicationBarIconButton();
AddButton.IconUri = new Uri("/Images/add.png", UriKind.Relative);
AddButton.Text = "Add Photo";
ApplicationBar.Buttons.Add(AddButton);
AddButton.Click +=AddButton_Click;
//Dont add refresh button as it does not work at this time :(
ApplicationBarIconButton RefreshButton = new ApplicationBarIconButton();
RefreshButton.IconUri = new Uri("/Images/refresh.png", UriKind.Relative);
RefreshButton.Text = "Refresh";
ApplicationBar.Buttons.Add(RefreshButton);
RefreshButton.Click += RefreshButton_Click;
}
private void RefreshButton_Click(object sender, EventArgs e)
{
GetThemeParkPhotos();
}
private void AddButton_Click(object sender, EventArgs e)
{
//need to send them to add a photo page with details.
NavigationService.Navigate(new Uri("/TakePhoto.xaml?pID=" + parkID + "&pName=" + parkName, UriKind.Relative));
}
Here the Code for the ListBox
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<ListBox Height="559" HorizontalAlignment="Left" Margin="6,20,0,0" x:Name="ThemeParkPhoto" VerticalAlignment="Top" Width="444" FontSize="30" ItemsSource="{Binding}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<TextBlock x:Name="ID" Text="{Binding ID}"></TextBlock>
<Image x:Name="PhotoURL" Source="{Binding PhotoURL}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
I have removed the URL to save the API, That code does run and fill it but why does it not refresh the List Box correctly?
Many Thanks
Thank to being sent here : C# WebClient disable cache
Turns out that Windows phone web client caches the file meaning it never download it again until the app is refreshed. By using a random number generator and adding it to the then of the URL it will always download the file allowing for a refresh.

Emptying a listbox programmatically

I want to clear listbox everytime when addImages button is clicked which adds new items to it but I am facing problem in clearing it. Following is my code:
private void addImages_Click(object sender, RoutedEventArgs e)
{
FileInfo Images;
string[] filenames = null;
System.Windows.Forms.FolderBrowserDialog folderDlg = new System.Windows.Forms.FolderBrowserDialog();
folderDlg.ShowNewFolderButton = true;
System.Windows.Forms.DialogResult result = folderDlg.ShowDialog();
if (result == System.Windows.Forms.DialogResult.OK)
{
filenames = System.IO.Directory.GetFiles(folderDlg.SelectedPath);
foreach (string image in filenames)
{
Images = new FileInfo(image);
if(Images.Extension.ToLower() == ".png" || Images.Extension.ToLower() == ".jpg" || Images.Extension.ToLower() == ".gif" || Images.Extension.ToLower() == ".jpeg" || Images.Extension.ToLower() == ".bmp" || Images.Extension.ToLower() == ".tif")
{
ImageList.Items.Add(new LoadImages(new BitmapImage(new Uri(image))));
}
}
}
}
I have tried ImageList.items.clear(), BindingOperations.ClearAllBindings(ImageList) but these removed items first time only when button is clicked next time onwards they don't clear the list. I want list to be cleared everytime when button is clicked.
This code below should work properly. the only thing that might be problematic
private void addImages_Click(object sender, RoutedEventArgs e)
{
ImageList.Items.Clear();
RefreshList();
FileInfo Images;
string[] filenames = null;
System.Windows.Forms.FolderBrowserDialog folderDlg = new System.Windows.Forms.FolderBrowserDialog();
folderDlg.ShowNewFolderButton = true;
System.Windows.Forms.DialogResult result = folderDlg.ShowDialog();
if (result == System.Windows.Forms.DialogResult.OK)
{
filenames = System.IO.Directory.GetFiles(folderDlg.SelectedPath);
foreach (string image in filenames)
{
Images = new FileInfo(image);
if(new string[]{".png", ".jpg", ".gif", ".jpeg", ".bmp", ".tif"}.Contains(Images.Extension.ToLower()))
{
ImageList.Items.Add(new LoadImages(new BitmapImage(new Uri(image))));
}
}
}
RefreshList();
}
private void RefreshList()
{
// Force visual refresh of control
ImageList.Refresh();
}
*note i cleaned up the extension validation
Edit : I just noticed you talk about Bindings. well you problem is easy then. you cannot clear a list binded to a control. the control will keep original source. You can only UPDATE a binding source otherwise you need to manually update the binding.
Binding on collection is a like a climbing.
Control is the person
Ropes are the DataSource(collection)
Mountain is your model
If in your model you clear (cut) the source (all ropes)
the Control (person) still hold the source (ropes)
If you want the control (person) to have a new source (rope)
You need to add a new one so he can jump on it an remove old ones.
ListBox.Items.Clear should clear the list, if you need that to happen every time the button is clicked then you need it in your event handler i.e.
private void addImages_Click(object sender, RoutedEventArgs e)
{
listBox.Items.Clear();
// do stuff
}
Try this ..
ImageList.Images.Clear();
listBox.Items.Clear();

How can I drag a folder from my Windows Explorer into a ListView and load the files into it?

I can't seem to make this work using this:
private void listView1_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
e.Effect = DragDropEffects.Copy;
}
}
private void listView1_DragDrop(object sender, DragEventArgs e)
{
string[] directoryName = (string[])e.Data.GetData(DataFormats.FileDrop);
string[] files = Directory.GetFiles(directoryName[0]);
foreach (string file in files)
{
if (Path.GetExtension(file) == ".mp3")
{
listView1.Items.Add(file);
}
}
}
The mouse cursor shows a NOT sign and I can't drop the folder in my program.
Have you set the AllowDrop property of your ListView to True?
Is your DragEnter event ever being hit?

Categories