I'm having a problem with dragging and dropping files onto a richTextBox, every time I drag a text file onto it, it turns into a picture of the text file with its name under it. Double click the file and it opens up using the system default application (ie notepad for text files, etc). basically its making shortcuts in the richTextBox, when i want it to read the text in the file.
Based on this code, the text from the file should extract into richTextBox1
class DragDropRichTextBox : RichTextBox
{
public DragDropRichTextBox()
{
this.AllowDrop = true;
this.DragDrop += new DragEventHandler(DragDropRichTextBox_DragDrop);
}
private void DragDropRichTextBox_DragDrop(object sender, DragEventArgs e)
{
string[] fileNames = e.Data.GetData(DataFormats.FileDrop) as string[];
if (fileNames != null)
{
foreach (string name in fileNames)
{
try
{
this.AppendText(File.ReadAllText(name) + "\n");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
}
Any ideas on how to make this work?
you need to check the draged object before you are reading into file. try below code.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
richTextBox1.DragDrop += new DragEventHandler(richTextBox1_DragDrop);
richTextBox1.AllowDrop = true;
}
void richTextBox1_DragDrop(object sender, DragEventArgs e)
{
object filename = e.Data.GetData("FileDrop");
if (filename != null)
{
var list = filename as string[];
if (list != null && !string.IsNullOrWhiteSpace(list[0]))
{
richTextBox1.Clear();
richTextBox1.LoadFile(list[0], RichTextBoxStreamType.PlainText);
}
}
}
use this to bind DragEnter and DragDrop event for RichTextBox in Designer.cs
this.richTextBox1.AllowDrop = true; this.richTextBox1.DragDrop += new System.Windows.Forms.DragEventHandler(this.textBox1_DragDrop); this.richTextBox1.DragEnter += new System.Windows.Forms.DragEventHandler(this.textBox1_DragEnter);
private void textBox1_DragDrop(object sender, DragEventArgs e)
{
try
{
Array a = (Array)e.Data.GetData(DataFormats.FileDrop);
if (a != null)
{
string s = a.GetValue(0).ToString();
this.Activate();
OpenFile(s);
}
}
catch (Exception ex)
{
MessageBox.Show("Error in DragDrop function: " + ex.Message);
}
}
private void OpenFile(string sFile)
{
try
{
StreamReader StreamReader1 = new StreamReader(sFile);
richTextBox1.Text = StreamReader1.ReadToEnd();
StreamReader1.Close();
}
catch (Exception ex)
{
MessageBox.Show(this, ex.Message, "Error loading from file");
}
}
private void textBox1_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
e.Effect = DragDropEffects.Copy;
else
e.Effect = DragDropEffects.None;
}
For starters, Kazankoph is incorrect when he tells you there is no "AllowDrop."
He made this statement in 2013, and AllowDrop has existed since NET Framework was released on 13 February 2002. You'll find this at the link below.
In fact, it is code you can use in Vb.net as well. As for the "EnableAutoDragDrop" if you go to your form design and "right-click" on the RichTextBox and go to "Properties", you'll find that "EnableAutoDragDrop" is normally set at "False" and you have to set the properties manually to "True." I took a screenshot of my code just to prove that "AllowDrop" does exist. I am placing the code I use to Drag & Drop in the event you find it useful. Be sure to EnableAutoDragDrop in properties as explained above.
Granted this is a C# question, he's backing for my statement of AllowDrop for C#, with an example:
https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.richtextbox.allowdrop?view=windowsdesktop-6.0
Private Sub RichTextBox1_TextChanged(sender As Object, e As EventArgs) Handles RichTextBox1.TextChanged
AllowDrop = True
AddHandler RichTextBox1.DragEnter, New DragEventHandler(AddressOf RichTextBox1_DragEnter)
AddHandler RichTextBox1.DragDrop, New DragEventHandler(AddressOf RichTextBox1_DragEnter)
End Sub
'Drag Load RichTextBox1
Private Sub RichTextBox1_DragDrop(sender As Object, e As DragEventArgs)
' Loads the file into the control.
RichTextBox1.LoadFile(CType(e.Data.GetData(Text), String), RichTextBoxStreamType.RichText)
End Sub
'Drag Effects RichTextBox1
Private Sub RichTextBox1_DragEnter(sender As Object, e As DragEventArgs)
If e.Data.GetDataPresent(DataFormats.Text) Then
CType(e, DragEventArgs).Effect = DragDropEffects.Copy
Else
CType(e, DragEventArgs).Effect = DragDropEffects.None
End If
End Sub
Related
I'm having trouble loading a file into a RichText control.
First, there are no events in the designer to accomodate drag/drop, so I put these handlers in the form initialization.
Second, the DragEnter() event does not seem to identify text files properly, so dropping is disabled in the RichText (it works fine for a ListBox).
Third, if I get the RT to load the file, it displays an icon/filename inside the RT text area. I cant find any references to this behavior, and can't turn it off.
This code does NOT work:
public Form1()
{
InitializeComponent();
RT.AllowDrop = true;
RT.DragEnter += new System.Windows.Forms.DragEventHandler(RT_DragEnter);
RT.DragDrop += new System.Windows.Forms.DragEventHandler(RT_DragDrop);
}
private void RT_DragEnter(object sender, System.Windows.Forms.DragEventArgs e) {
// when a text file is dragged to this control, GetDataPresent() returns FALSE.
// this seems to be regardless of the file extension. File is ASCII text only.
// this code DOES work if the underlying control is a ListBox.
if (e.Data.GetDataPresent(DataFormats.Text))
e.Effect = DragDropEffects.Move;
else
e.Effect = DragDropEffects.None;
}
private void RT_DragDrop(object sender, System.Windows.Forms.DragEventArgs e) {
string[] filenames = (string[])e.Data.GetData(DataFormats.FileDrop, false);
if (null != filenames){
// when the file is loaded, the RT also displays an icon for the file,
// with the filename, inside the text area ... ?
RT.LoadFile(filenames[0],RichTextBoxStreamType.PlainText);
}
}
In order to get the RT to load a dropped file properly, I use a timer to load the RT outside of the
DragDrop() event:
public string FileToLoad;
private void RT_DragEnter(object sender, System.Windows.Forms.DragEventArgs e) {
// allow anything:
//if (e.Data.GetDataPresent(DataFormats.Text))
e.Effect = DragDropEffects.Move;
//else
//e.Effect = DragDropEffects.None;
}
private void RT_DragDrop(object sender, System.Windows.Forms.DragEventArgs e) {
string[] filenames = (string[])e.Data.GetData(DataFormats.FileDrop, false);
if (null != filenames){
FileToLoad = filenames[0];
timer1.Enabled = true;
}
}
private void timer1_Tick(object sender, EventArgs e)
{
timer1.Enabled = false;
if (FileToLoad.Length > 0)
{
RT.LoadFile(FileToLoad, RichTextBoxStreamType.PlainText);
FileToLoad = "";
}
}
The latter has the RichText loading the file properly, but this seems like a long way around the block to get LoadFile() to work as expected. Am I doing something wrong?
I have a windows form that reads strings from a file and shows them all in a textbox when I press a button.
private void buttonTxt_Click(object sender, EventArgs e)
{
string[] Test = File.ReadAllLines("C:\\testfile.txt");
for (int i = 0; i < testfile.Length; i++)
{
TextBox.Text += testfile[i];
}
}
I'd like to make two radio buttons. So that first button lets my program work the way I described (by default) AND second radio button makes it work vice versa -- so that I could write in a textbox myself and when I press a button it writes a new line to the same file. Is there a way to do it?
Simply add an if statement in this event handler and implement both sending and receiving the data. Done. Sample in principle:
private const string FilePath = #"C:\testfile.txt";
private void buttonTxt_Click(object sender, EventArgs e)
{
if (radioReadMode.Checked) // check which radio button is selected
{ // read mode
string[] Test = File.ReadAllLines(FilePath);
for (int i = 0; i < testfile.Length; i++)
TextBox.Text += testfile[i];
}
else
{ // write mode
File.WriteAllText(FilePath, TextBox.Text);
}
}
I believe this is what you might be looking for. If radio button 1 is checked then if the file exists it will read that file and put it into a textbox in the form. If you switch to radio button 2. You can type in the text box and then when you press the button it will append it to the file.
public partial class Form1 : Form
{
System.IO.StreamReader sr;
System.IO.StreamWriter sw;
public Form1()
{
InitializeComponent();
radioButton1.Checked = true;
}
private void button1_Click(object sender, EventArgs e)
{
if (radioButton1.Checked == true)
{
if (System.IO.File.Exists("C:\\testfile.txt"))
{
try
{
sr = new System.IO.StreamReader("C:\\testfile.txt");
while (!sr.EndOfStream)
{
textBox1.Text += sr.ReadLine() + "\r\n";
}
}
finally
{
sr.Close();
sr.Dispose();
}
}
}
if (radioButton2.Checked == true)
{
if (System.IO.File.Exists("C:\\testfile.txt"))
{
try
{
sw = new System.IO.StreamWriter("C:\\testfile.txt", true);
string result = textBox1.Text;
string[] lststr = result.Split(new Char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
foreach (string s in lststr)
{
sw.WriteLine(s);
}
}
finally
{
sw.Flush();
sw.Close();
sw.Dispose();
}
}
}
}
private void radioButton1_CheckedChanged(object sender, EventArgs e)
{
textBox1.Clear();
textBox1.ReadOnly = true;
}
private void radioButton2_CheckedChanged(object sender, EventArgs e)
{
textBox1.Clear();
textBox1.ReadOnly = false;
}
}
Yes, there's a way. Just add another button to your form and inside read the text from the text box this way:
var textBoxContent = TextBox.Text;
and save it to your file this way
File.WriteAllText("C:\\testfile.txt", textBoxContent);
Note: I recommend getting the path to your file into a variable
I have one windows application in c#, i want to add drag & drop facility in this application, after adding this facility it takes multiple files, so I want to take only one file at a time, how to do this?
read the code below and try applying it to your situation
public Form1()
{
InitializeComponent();
this.AllowDrop = true;
this.DragEnter += Form1_DragEnter;
this.DragDrop += Form1_DragDrop;
}
void Form1_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
e.Effect = DragDropEffects.Copy;
}
void Form1_DragDrop(object sender, DragEventArgs e)
{
var files = (string[])e.Data.GetData(DataFormats.FileDrop);
if (files.Length == 1)
{
// do what you want
}
else
{
// show error
}
}
I did some research and found this :
DataObject d = new DataObject();
d.SetData(DataFormats.Serializable, myObject);
d.SetData(DataFormats.Text, myObject.ToString());
myForm.DoDragDrop(d, DragDropEffects.Copy);
code snippet to drag drop in win forms.
And i tried implementing it like this (WPF) :
private void listView1_MouseMove(object sender, MouseEventArgs e)
{
try
{
if (e.LeftButton == MouseButtonState.Pressed)
{
DataObject d = new DataObject();
d.SetData(DataFormats.Serializable, listView1.SelectedItem);
d.SetData(DataFormats.Text, listView1.SelectedItem.ToString());
DragDrop.DoDragDrop(listView1, d, DragDropEffects.Copy);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Now I had thought when i drag dropped the ListViewItem into notepad it would probably copy the class name of the selected item (Because that's what listView1.SelectedItem.ToString()) is... But instead Notepad showed a picture of a cancel symbol while hovering, and copied nothing when i let go of the mouse button.
The over all goal of this is to change the class into a comma delimited string so when it copy pastes into notepad all of the data of the class will be in a nice format.
But if someone could help me just get the class name to copy i'm sure i could figure it out from there :o
So.... Yea.
bool alreadycopying = false;
private void listView1_MouseMove(object sender, MouseEventArgs e)
{
try
{
if (e.LeftButton == MouseButtonState.Released)
{
alreadycopying = false;
}
if (e.LeftButton == MouseButtonState.Pressed && alreadycopying == false)
{
alreadycopying = true;
System.IO.StreamWriter test = new System.IO.StreamWriter(#"C:\SuperSecretTestFile.txt");
test.WriteLine("Test");
test.Close();
List<String> testlist = new List<string>();
testlist.Add(#"C:\SuperSecretTestFile.txt");
DataObject d = new DataObject();
d.SetData(DataFormats.FileDrop, testlist.ToArray<string>());
DragDrop.DoDragDrop(listView1, d, DragDropEffects.All);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
After much bashing of poor notepad technology, c# comes out victorious <.<
I am writing a little program in C# that scans a folder and opens the files that have been created after 5.30pm after a button has been pressed on the program. This will also have to search within sub-folders.
I need a couple of solutions to point me in the correct direction as I'm not sure how I would do this.
This is part of a folder watcher program. The problem is when the user goes home the PC is switched off and there are files being created to the directory after 17.30. So I need a way for when the program is restarted in the morning it detects anything created after 17.30 and open them.
private void button1_Click(object sender, EventArgs e)
{
folderBrowser.ShowDialog();
textBox1.Text = folderBrowser.SelectedPath;
filewatcher.Path = textBox1.Text;
Registry.SetValue("HKEY_CURRENT_USER\\SOFTWARE\\COMPANY\\FOLDERWATCHER", "FOLDERPATH", textBox1.Text);
}
private void Form1_Load(object sender, EventArgs e)
{
String WatchFolder = Registry.GetValue("HKEY_CURRENT_USER\\SOFTWARE\\COMPANY\\FOLDERWATCHER", "FOLDERPATH", "").ToString();
textBox1.Text = WatchFolder;
filewatcher.Path = WatchFolder;
}
private void Form1_Resize(object sender, EventArgs e)
{
if (WindowState == FormWindowState.Minimized)
{
ShowInTaskbar = true;
Hide();
}
}
private void fileSystemWatcher1_Changed(object sender, System.IO.FileSystemEventArgs e)
{
if(!e.FullPath.EndsWith("temp.temp"))
{
MessageBox.Show("You have a Collection Form: " + e.Name);
Process.Start("explorer.exe", e.FullPath);
}
}
private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
{
Show();
}
}
This is my complete code above. I would like to use a button to open or show the files created after 17.30.
Look at the System.IO namespace, it has everything you need.
the DirectoryInfo and File classes will do what you want.
Here is the recursive method you are looking for:
public static List<string> GetFilesCreatedAfter(string directoryName, DateTime dt)
{
var directory = new DirectoryInfo(directoryName);
if (!directory.Exists)
throw new InvalidOperationException("Directory does not exist : " + directoryName);
var files = new List<string>();
files.AddRange(directory.GetFiles().Where(n => n.CreationTime > dt).Select(n=>n.FullName));
foreach (var subDirectory in Directory.GetDirectories(directoryName))
{
files.AddRange(GetFilesCreatedAfter(subDirectory,dt));
}
return files;
}
Hope I helped.
You can use FileSystemWatcher (MSDN documentation) to detect files that have been created after pressing a button (while your application is running).
FileSystemWatcher watcher = new FileSystemWatcher();
watcher.Path = "C:\\YourDirectory";
watcher.Created += (sender, args) => {
// File was created
}
watcher.EnableRaisingEvents = true;
This allows you to track files as they are created (while your application is running).
If you just want to get a list of all directories that were created in a specified time range (before your application was started), then you can search the directory tree using Directory.GetDirectories and Directory.GetFiles.
In place of datetime place you date and time value.
void DirSearch(string dir)
{
try
{
foreach (string d in Directory.GetDirectories(dir))
{
foreach (string f in Directory.GetFiles(d, "*.*"))
{
if(DateTime.Compare(f.GetCreationTime, datetime))
{
//files found
}
}
DirSearch(d);
}
}
catch (System.Exception excpt)
{
Console.WriteLine(excpt.Message);
}
}