C# Drag and Drop text within a RichTextBox - c#

I have a C# project in which I want the user to be able to drag and drop text (i.e. to move text) within a RichTextBox in a WinForm.
I have found many examples showing how to do drop something onto a RichTextBox but I didn't succeed to have them work when the RichTextBox is both the drag source and drop target.
How should I do this ?
Below is my non-working attempt sofar.
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
this.richTextBox1.AllowDrop = true;
this.richTextBox1.DragEnter += new System.Windows.Forms.DragEventHandler(this.richTextBox1_DragEnter);
this.richTextBox1.DragDrop += new System.Windows.Forms.DragEventHandler(this.richTextBox1_DragDrop);
}
private void richTextBox1_DragEnter(object sender, System.Windows.Forms.DragEventArgs e) {
if (e.Data.GetDataPresent(DataFormats.Rtf))
e.Effect = DragDropEffects.Move;
else
e.Effect = DragDropEffects.None;
}
private void richTextBox1_DragDrop(object sender, System.Windows.Forms.DragEventArgs e) {
int i;
String s;
i = richTextBox1.SelectionStart;
s = richTextBox1.Text.Substring(i);
richTextBox1.Text = richTextBox1.Text.Substring(0, i);
richTextBox1.Text = richTextBox1.Text +
e.Data.GetData(DataFormats.Text).ToString();
richTextBox1.Text = richTextBox1.Text + s;
}
}

Well, I found myself a solution to this problem :
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
richTextBox1.EnableAutoDragDrop = true;
}
}
And nothing more.
My first attempt was based on MSDN documentation:
http://msdn.microsoft.com/en-us/library/aa984395(v=vs.71).aspx, but it seems broken.

Drag and drop text within RXBox (RichTextBox):
Run HookOn_EventHandlers_etc() during Initialize(). Dragging mouse will fire the DragEnter and DragDrop events. In RXBox_DragDrop(), set DragDropEffects back to None.
private void HookOnEventHandlers_etc()
{
RXBox.DragEnter += RXBox_DragEnter;
RXBox.DragDrop += RXBox_DragDrop;
RXBox.AllowDrop = true;
RXBox.EnableAutoDragDrop = true;
}
private void RXBox_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.Text))
e.Effect = DragDropEffects.Copy;
else
e.Effect = DragDropEffects.None;
}
private void RXBox_DragDrop(object sender, DragEventArgs e)
{
RXBox.SelectedText = e.Data.GetData(DataFormats.Text).ToString();
e.Effect = DragDropEffects.None; // with this the paste won't be doubled
}

Related

c# How do I drag and drop text from label into a specific cell in a datagridview

I'm trying to put text in a specific cell using drag and drop screenshot of my screen
There is a simplified solution provided here, please check -
https://www.codeproject.com/Questions/101532/How-to-apply-drag-drop-cell-content-in-datagridvie
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
//allow drop
this.dataGridView1.AllowDrop = true;
//data grid view sample data
DataTable dtb = new DataTable();
dtb.Columns.AddRange(new DataColumn[] { new DataColumn(), new DataColumn(), new DataColumn() });
for (int i = 0; i < 30;)
{
dtb.Rows.Add((++i).ToString(), (++i).ToString(), (++i).ToString());
}
dataGridView1.DataSource = dtb;
}
private void dataGridView1_CellMouseMove(object sender, DataGridViewCellMouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
dataGridView1.DoDragDrop(dataGridView1[e.ColumnIndex,e.RowIndex].FormattedValue, DragDropEffects.Copy);
}
}
private void dataGridView1_DragDrop(object sender, DragEventArgs e)
{
string cellvalue=e.Data.GetData(typeof(string)) as string;
Point cursorLocation=this.PointToClient(new Point(e.X,e.Y));
System.Windows.Forms.DataGridView.HitTestInfo hittest= dataGridView1.HitTest(cursorLocation.X,cursorLocation.Y);
if (hittest.ColumnIndex != -1
&& hittest.RowIndex != -1)
dataGridView1[hittest.ColumnIndex, hittest.RowIndex].Value = cellvalue;
}
private void dataGridView1_DragOver(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Copy;
}
}

Trying to create Drag and Drop with PictureBoxes - events don't trigger

EDIT 1/Resolution:
Okay I found what was missing. I did not set any event handlers.
Now it works with the following
public Form1()
{
InitializeComponent();
pictureBox1.DragEnter += new DragEventHandler(pictureBox1_DragEnter);
pictureBox1.DragDrop += new DragEventHandler(pictureBox1_DragDrop);
}
So my next question would be....why do I have to set these? Something like a ButtonClick knows exactly where to go...so why wouldn't these other events?
I'm still a little new to C#.
-
ORIGINAL QUESTION:
I'm messing around with dragging and dropping images into a picturebox from my computer.
I have a working version of this in VB. So I just translated (as best I could) it all into C#.
My DragEnter event isn't even triggering at all...I'm not sure what I am missing.
I had to change some things because of the C#/VB differences, but it's basically the same code. I feel like I am missing more events or something...I just don't know what.
Even if it does turn out I have some code wrong...my program never even fires DragEnter....if I put a dummy Debug line or MessageBox in that event just to see if it ran.....it never does.
My form load
private void Form1_Load(object sender, EventArgs e)
{
pictureBox1.AllowDrop = true;
pictureBox1.BorderStyle = BorderStyle.FixedSingle;
this.AllowDrop = true;
}
My DragEnter
private void pictureBox1_DragEnter(object sender, DragEventArgs e)
{
string[] formats = e.Data.GetFormats();
if (e.Data.GetDataPresent(DataFormats.Bitmap))
{
if (e.KeyState == CtrlMask && CtrlMask == CtrlMask)
{
e.Effect = DragDropEffects.Copy;
}
else
{
e.Effect = DragDropEffects.Move;
}
}
else if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
e.Effect = DragDropEffects.All;
}
else if (e.Data.GetDataPresent(DataFormats.Rtf))
{
if (e.KeyState == CtrlMask && CtrlMask == CtrlMask)
{
e.Effect = DragDropEffects.Copy;
}
else
{
e.Effect = DragDropEffects.Move;
}
}
}
And my DragDrop..
private void pictureBox1_DragDrop(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.Bitmap))
{
var bmp = (Bitmap)e.Data.GetData(DataFormats.Bitmap);
pictureBox1.Image = bmp;
}
else if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
string[] files;
files = (string[])e.Data.GetData(DataFormats.FileDrop);
foreach (string file in files)
{
string Newfile = file.ToLower();
string[] ImageTypes = { "gif", "jpg", "png", "bmp" };
string ActualFileExt = "";
foreach (string FileExtension in ImageTypes)
{
if (Newfile.EndsWith(FileExtension))
{
ActualFileExt = FileExtension;
}
}
if (ActualFileExt != "")
{
pictureBox1.Image = new Bitmap(Newfile);
}
}
}
else if (e.Data.GetDataPresent(DataFormats.Rtf))
{
}
}
You had to explicitly add the handlers since you did not use the 'Handles' keyword after your drop/enter methods. Notice the example code in this example uses the Handles keyword similar to a button.

C# - How to save a string entered in Form2 in Form1

I get the default path from the registry for the Steam installation. But if someone has their games installed to a different folder, the user has to enter it in the Configure form. When the form gets closed, that path entered(from the folder browser or by typing the path in manually) should get saved to a string in the main form and should enable a different Combobox which turns on different buttons. I somehow managed to do the save to the mainform string, but the 2nd combobox doesn't seem to turn on. How can I do it correctly?
** MAIN FORM **
public string NewPath { get; set; }
private ConfigForm otherForm;
string InstallPath = (string)Registry.GetValue(#"HKEY_CURRENT_USER\SOFTWARE\Valve\Steam", "SteamPath", null);
private void PortalHammerButton_Click(object sender, EventArgs e)
{
Process.Start(InstallPath + #"\SteamApps\common\Portal\bin\hammer.exe");
}
private void Gamedropdown_SelectedIndexChanged(object sender, EventArgs e)
{
if (Gamedropdown.Text == "Portal") // When Portal is selected
{
// Enable the Portal SDK buttons
PortalHammerButton.Visible = true;
PortalModelViewerButton.Visible = true;
PortalFacePoserButton.Visible = true;
// Disable the CS:GO SDK buttons
csgoFacePoserButton.Visible = false;
csgoHammerButton.Visible = false;
csgoModelViewerButton.Visible = false;
}
else if (Gamedropdown.Text == "CS:GO") // When CS:GO is selected
{
// Disable Portal SDK buttons
PortalHammerButton.Visible = false;
PortalModelViewerButton.Visible = false;
PortalFacePoserButton.Visible = false;
// Enable CS:GO SDK buttons
csgoFacePoserButton.Visible = true;
csgoHammerButton.Visible = true;
csgoModelViewerButton.Visible = true;
}
}
private void ConfigureButton_Click(object sender, EventArgs e)
{
var configdialog = new ConfigForm();
configdialog.Show();
}
private void PortalDifferentHammerButton_Click(object sender, EventArgs e)
{
Process.Start(NewPath + #"\SteamApps\common\Portal\bin\hammer.exe");
}
private void NewDropDown_SelectedIndexChanged(object sender, EventArgs e)
{
if (NewDropDown.Text == "Portal") // When Portal is selected
{
// Enable the Portal SDK buttons
PortalDifferentHammerButton.Visible = true;
PortalDifferentModelViewerButton.Visible = true;
PortalDifferentFacePoserButton.Visible = true;
// Disable the CS:GO SDK buttons
DifferentCSGOFaceposerButton.Visible = false;
DifferentCSGOHammerButton.Visible = false;
DifferentCSGOModelViewerButton.Visible = false;
}
else if (NewDropDown.Text == "CS:GO") // When CS:GO is selected
{
// Disable the Portal SDK buttons
PortalDifferentFacePoserButton.Visible = false;
PortalDifferentHammerButton.Visible = false;
PortalDifferentModelViewerButton.Visible = false;
// Enable the CS:GO SDK buttons
DifferentCSGOModelViewerButton.Visible = true;
DifferentCSGOHammerButton.Visible = true;
DifferentCSGOFaceposerButton.Visible = true;
}
}
private void button1_Click(object sender, EventArgs e)
{
this.Close();
ConfigForm cfgfrm = new ConfigForm();
cfgfrm.Close();
}
}
}
**CONFIGURE FORM**
public partial class ConfigForm : Form
{
public ConfigForm()
{
InitializeComponent();
Form1 frm1 = new Form1();
frm1.NewPath = NewPathBox.Text;
}
public void DifferentFolderBrowseButton_Click(object sender, EventArgs e)
{
FolderBrowserDialog fbd = new FolderBrowserDialog();
DialogResult result = fbd.ShowDialog();
string newpath = fbd.SelectedPath;
NewPathBox.Text = newpath;
Form1 frm1 = new Form1();
frm1.NewPath = NewPathBox.Text;
}
public void CloseButton_Click(object sender, EventArgs e)
{
this.Hide();
Form1 frm1 = new Form1();
frm1.Gamedropdown.Visible = false;
frm1.NewDropDown.Visible = true;
}
}
}
Any help would be appriciated.
Look at your ConfigForm. Here's your problem:
public ConfigForm()
{
InitializeComponent();
Form1 frm1 = new Form1();
frm1.NewPath = NewPathBox.Text;
}
What you're doing on your Form1 (which I'm guessing is your Main form) is creating a new instance of your ConfigForm and showing it. What you're doing in your ConfigForm is creating a new main form and setting the NewPath = to the value entered on your config form. The problem is this new Form1 is NOT the Form1 that created the ConfigForm. The Form1 that created your config form is not the one getting updated by your code, some arbitrary new Form1 that you create is the one getting updated. This is why your code isn't working as you expected.
Here's the approach I would take. Add a NewPath variable to your ConfigForm just like you have in Form1. Then, add a FormClosing method to FormConfig. Do something like this:
private void ConfigForm_FormClosing(object sender, FormClosingEventArgs e)
{
NewPath = NewPathBox.Text;
}
Then, change your code on Form1 to this:
private void button1_Click(object sender, EventArgs e)
{
ConfigForm cfgfrm = new ConfigForm();
cfgfrm.ShowDialog();
this.NewPath = cfgfrm.NewPath;
}
What this code is doing is creating and showing a new ConfigForm on your Form1 when you click button1. Then, when your user closes the FormConfig, the form saves the textbox value to the NewPath variable on the FormConfig. Then, once the form is closed, the code on Form1 resumes. Form1 then looks at the NewPath value that was saved when the user closed the FormConfig. Form1 grabs this new NewPath value and puts it in its own NewPath variable.
EDIT
To show/hide comboboxes:
private void button1_Click(object sender, EventArgs e)
{
ConfigForm cfgfrm = new ConfigForm();
cfgfrm.ShowDialog();
this.NewPath = cfgfrm.NewPath;
Gamedropdown.Visible = false;
NewDropDown.Visible = true
}
I'm not sure why you are making the secondary form so complicated. You don't need a pointer to it after you use it and you should be closing instead of hiding. Try this:
class ConfigForm : Form
{
public string newPath = null;
public void CloseButton_Click(object sender, EventArgs e)
{
newPath = NewPathBox.Text;
}
public void CloseButton_Click(object sender, EventArgs e)
{
Close();
}
}
...and in your main form:
public partial class Form1 : Form
{
string steamPath = null; // set to starting path
private void ConfigureButton_Click(object sender, EventArgs e)
{
bool valueChanged = false;
using (ConfigForm form = new ConfigForm())
{
form.newPath = null;
form.ShowDialog();
if (form.newPath != null)
{
steamPath = form.newPath;
valueChanged = true;
}
}
if (valueChanged)
{
// here is where you would handle reloading and changing the ComboBoxes
}
}
}
This will more cleanly return the new string. Whatever you want to do as a result of having changed the path can be done after you have disposed of the config form (bringing it up with the "using" conditional automatically does the disposal for you)

C# - Create dynamic buttons and events

I have a form with a tabControl and inside of each tab is a flowLayoutPanel where I can drag and drop files and a button is created for each dropped file. Afterwards when I click on a button, the file that i dropped should open. I have managed to do this for one file only.. My problem is how can I tell which button was clicked and to open the file/app stored in the path for each button.. How can I differentiate in the button_click event the clicked button and the path of the app to open?
Code for this part so far:
Process myProcess = new Process();
string path_app;
public Form1()
{
InitializeComponent();
this.DragEnter += new DragEventHandler(Form1_DragEnter);
this.DragDrop += new DragEventHandler(Form1_DragDrop);
}
void Form1_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop, false))
e.Effect = DragDropEffects.All;
}
void Form1_DragDrop(object sender, DragEventArgs e)
{
string[] fileList = e.Data.GetData(DataFormats.FileDrop) as string[];
foreach (string s in fileList)
{
Button button = new Button();
button.Click += new EventHandler(this.button_Click);
flowLayoutPanel1.Controls.Add(button);
path_app = String.Format("{0}", s);
}
}
private void button_Click(object sender, System.EventArgs e)
{
myProcess.StartInfo.FileName =path_app;
myProcess.Start();
}
Also my tabControl has the possibility to add new tabs but how can I get the selected tab and the inside flowLayoutPanel to know where to create the button?
And by the way, is there a problem of how I open the files? I understood that i have to take into consideration the working directory..
Thank you for your help!
You can utilize Tag property of the Button:
void Form1_DragDrop(object sender, DragEventArgs e)
{
foreach (String s e.Data.GetData(DataFormats.FileDrop))
{
Button button = new Button();
button.Click += new EventHandler(this.button_Click);
flowLayoutPanel1.Controls.Add(button);
path_app = String.Format("{0}", s);
// Add to Tag any data you want to pin to the button
button.Tag = path_app;
}
}
private void button_Click(object sender, System.EventArgs e)
{
// Obtain via Tag
String path_app = ((sender as Button).Tag as String);
myProcess.StartInfo.FileName = path_app;
myProcess.Start();
}
You could use button.Tag = "theFancyPath" and in the EventHandler cast the object sender as Button to access the Tag property.
If you need more then you could inherit from Button:
public class ButtonWithPathProperty : Button
{
public FileInfo PathToOpen { get; private set; }
public ButtonWithPathProperty(FileInfo path)
{
PathToOpen = path;
this.Click += new EventHandler(this.button_Click);
}
private void button_Click(object sender, System.EventArgs e)
{
var yourPath = this.PathToOpen;
}
}
This is not tested btw :)

Display dropped image on Form

I have a C# app and i want it that when an Image is dropped on the form, A picturebox in the form displays the Image. I have tried this
private void Form1_DragEnter(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Move;
}
private void Form1_DragDrop(object sender, DragEventArgs e)
{
Graphics p = pictureBox1.CreateGraphics();
p.DrawImage((Image)e.Data.GetData(DataFormats.Bitmap), new Point(0, 10));
}
But it doesn't work.
Pls what did i do wrong?
I think you are dragging from file.
Simple code for this will be such:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.AllowDrop = true;
this.DragDrop += new System.Windows.Forms.DragEventHandler(this.Form1_DragDrop);
this.DragEnter += new System.Windows.Forms.DragEventHandler(this.Form1_DragEnter);
}
private void Form1_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
e.Effect = DragDropEffects.Copy;
}
else
{
e.Effect = DragDropEffects.None;
}
}
private void Form1_DragDrop(object sender, DragEventArgs e)
{
string[] filex = (string[])e.Data.GetData(DataFormats.FileDrop);
if (filex.Length > 0)
{
pictureBox1.ImageLocation = filex[0];
}
}
}
i truly hope this is not the solution but you didn't gave much information so i'll start here and we'll go as you give us more information.
when you toke this sample did you bind it to the proper events?
as in:
this.DragDrop += new System.Windows.Forms.DragEventHandler(this.Form1_DragDrop);
this.DragEnter += new System.Windows.Forms.DragEventHandler(this.Form1_DragEnter);
also, on initializing, did you do:
AllowDrop = true;

Categories

Resources