I have a tabControl and a flowLayoutPanel inside each tab.. When I drag and drop a file onto a tab it creates a button with the icon of the file dropped. But i have the option to create more tabs and I want to be able to drag files into the selected tab.. but the problem is the flowLayoutPanel when adding the button..
My code so far:
public Process myProcess = new Process();
FlowLayoutPanel fl_panel = new FlowLayoutPanel();
string path_app;
public Form1()
{
InitializeComponent();
//add the flowLayoutPanel on the first tab
fl_panel.Dock = DockStyle.Fill;
fl_panel.BringToFront();
tabPage1.Controls.Add(fl_panel);
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);
fl_panel.Controls.Add(button);
path_app = String.Format("{0}", s);
button.Tag = path_app;
string filename = path_app;
Icon icon = System.Drawing.Icon.ExtractAssociatedIcon(filename);
Bitmap bmp = icon.ToBitmap();
button.BackgroundImage = bmp;
button.Width = 60;
button.Height = 75;
button.FlatStyle = FlatStyle.Flat;
button.BackgroundImageLayout = ImageLayout.Stretch;
}
}
private void button_Click(object sender, System.EventArgs e)
{
String path_app = ((sender as Button).Tag as String);
myProcess.StartInfo.FileName = path_app;
myProcess.Start();
}
private void add_tab_btn_Click(object sender, EventArgs e)
{
//Create new tab with FLP inside
string title = Convert.ToString(textBox1.Text);
TabPage new_TabPage = new TabPage(title);
fl_panel.Dock = DockStyle.Fill;
fl_panel.BringToFront();
new_TabPage.Controls.Add(fl_panel);
tabControl1.TabPages.Add(new_TabPage);
}
}
If I use fl_panel.Controls.Add(button); it adds the buttons fine, on the first tab, but if I create a new tab I don't know how to use tabControl.SelectedTab with the fl_panel.Controls.Add(button) to add the buttons correctly on the selected tab.
You have to create a new FlowLayoutPanel for every tab:
FlowLayoutPanel fl_panel = new FlowLayoutPanel();
...
new_TabPage.Controls.Add(fl_panel);
And then you can cast the first element of the TabPage to the FlowLayoutPanel and access the Controls from there:
FlowLayoutPanel selectedFLP = (FlowLayoutPanel)tabControl.SelectedTab.Controls[0];
...
Related
hello I have a problem with TabControl. When I open the second Form it is always empty with no controls or anything.
my code. When I open the first tabpage everything is fine. Everything is in place
private void ShowFormInTabPage(TabPage tp , Form frm)
{
tabControl1.Controls.Add(tp);
frm.TopLevel = false;
tp.Text = frm.Text;
frm.Visible = true;
frm.FormBorderStyle = FormBorderStyle.None;
frm.Dock = DockStyle.Fill;
tabControl1.TabPages[0].Controls.Add(frm);
}
I add form to tabcontrol through such a method. the methods are the same in both cases
private void guna2Button1_Click(object sender, EventArgs e)
{
_tpEmployees = new TabPage();
if (EmployeesForm.IsNull)
{
ShowFormInTabPage(_tpEmployees , EmployeesForm.Instance);
}
else
{
tabControl1.SelectedTab = _tpEmployees;
}
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 :)
I create a custom control inside a tab control which contains a flowLayoutPanel on every tab by dragging files on the selected tab. I have a context menu to rename and delete tab pages, but i want also to be able to delete a button created when I right click on it and select "remove"... I cannot find a way to delete only the selected button..
This is what I have to create the buttons:
public void Form1_DragDrop(object sender, DragEventArgs e)
{
string[] fileList = e.Data.GetData(DataFormats.FileDrop) as string[];
foreach (string s in fileList)
{
var button = new Button();
path_app = String.Format("{0}", s);
string filename = path_app;
file_name = Path.GetFileName(path_app);
Icon icon = System.Drawing.Icon.ExtractAssociatedIcon(filename);
Bitmap bmp = icon.ToBitmap();
CustomControl custom_btn = new CustomControl(button, new Label { Text = file_name });
button.Tag = path_app;
button.BackgroundImage = bmp;
button.BackgroundImageLayout = ImageLayout.Stretch;
FlowLayoutPanel selectedFLP = (FlowLayoutPanel)tabControl1.SelectedTab.Controls[0];
selectedFLP.Controls.Add(custom_btn);
button.Click += new EventHandler(button_Click);
ContextMenu cm2 = new ContextMenu();
cm2.MenuItems.Add("Remove", new EventHandler(rmv_btn_click));
custom_btn.ContextMenu = cm2;
}
}
private void rmv_btn_click(object sender, System.EventArgs e)
{
foreach (Control X in fl_panel.Controls)
{
fl_panel.Controls.Remove(X);
}
}
How do I get the button which I right click on it as sender in the rmv_btn_click event to know which one to delete?
If I understand what you mean, You need to use something like this.
private void rmv_btn_click(object sender, System.EventArgs e)
{
fl_panel.Controls.Remove(sender as Button);
}
private void rmv_btn_click(object sender, System.EventArgs e)
{
Button btn = new Button();
Label lbl = new Label();
CustomControl cst_btn = new CustomControl(btn, lbl);
cst_btn = sender as CustomControl;
DialogResult dialogResult = MessageBox.Show("Are you sure that you want to remove this object?", "Remove object", MessageBoxButtons.YesNo);
if (dialogResult == DialogResult.Yes)
{
cst_btn.Dispose();
}
else if (dialogResult == DialogResult.No)
{
//do nothing
}
}
public EventHandler handlerGetter(CustomControl button)
{
return (object sender, EventArgs e) =>
{
rmv_btn_click(button, e);
};
}
I am trying to combine several ContextMenu items into one. Currently, I am using separate MenuItem for it to work. Is there a way to combine all these MenuItems into one WHILE being able to control each of these event triggers when the users click on the different MenuItems?
NotifyIcon notifyIcon = new NotifyIcon();
System.Windows.Forms.ContextMenu contextMenu = new System.Windows.Forms.ContextMenu();
System.Windows.Forms.MenuItem ChangeDetailsMenu = new System.Windows.Forms.MenuItem();
ChangeDetailsMenu.Text = "Change Contact Details";
ChangeDetailsMenu.Click += ChangeContactDetails;
System.Windows.Forms.MenuItem ChangeKinectAngleMenu = new System.Windows.Forms.MenuItem();
ChangeKinectAngleMenu.Text = "Change Kinect Angle";
ChangeKinectAngleMenu.Click += ChangeKinectAngle;
System.Windows.Forms.MenuItem exitMenu = new System.Windows.Forms.MenuItem();
exitMenu.Text = "Exit";
exitMenu.Click += ExitHandler;
contextMenu.MenuItems.Add(exitMenu);
contextMenu.MenuItems.Add(ChangeDetailsMenu);
contextMenu.MenuItems.Add(ChangeKinectAngleMenu);
Icon icon = new Icon("kse.ico");
notifyIcon.ContextMenu = contextMenu;
notifyIcon.Icon = icon;
notifyIcon.Visible = true;
private void ExitHandler(object sender, EventArgs e)
{
notifyIcon.Visible = false;
System.Windows.Application.Current.Shutdown();
}
private void ChangeContactDetails(object sender, EventArgs e)
{
}
private void ChangeKinectAngle(object sender, EventArgs e)
{
}
I am trying to mimic the behavior of, for example, Windows Explorer and how the Favorites items can launch a context menu.
I currently am using:
contextMenu.Show((sender as ToolStripMenuItem).GetCurrentParent().PointToScreen(e.Location));
This occurs in the MouseDown event of the ToolStripMenuItem. The problem is that the menu closes immediately after right-click, and I don't know any way to suspend it while the context menu is open.
I've tried deriving from ToolStripMenuItem and overriding the MouseDown/MouseUp but I can't figure out how to keep it open on click.
Is there a good way of doing this?
This is what I've had luck with, it's a bit more direct:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
void MenuItemContext(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left) return;
ToolStripMenuItem mID = (ToolStripMenuItem)sender;
ContextMenu tsmiContext = new ContextMenu();
MenuItem Item1 = new MenuItem();
MenuItem Item2 = new MenuItem();
Item1.Text = "Item1";
Item2.Text = "Item2";
tsmiContext.MenuItems.Add(Item1);
tsmiContext.MenuItems.Add(Item2);
Item1.Click += new EventHandler(Item1_Click);
Item2.Click += new EventHandler(Item2_Click);
hndPass = mID.Text;
tsmiContext.Show(menuStrip1, menuStrip1.PointToClient(new Point(Cursor.Position.X, Cursor.Position.Y)));
}
private String hndPass;
void Item1_Click(object sender, EventArgs e)
{
MenuItem mID = (MenuItem)sender;
MessageBox.Show("You clicked " + mID.Text + " in the context menu of " + hndPass);
}
void Item2_Click(object sender, EventArgs e)
{
MenuItem mID = (MenuItem)sender;
MessageBox.Show("You clicked " + mID.Text + " in the context menu of " + hndPass); ;
}
}
One way that you could accomplish this is by using the ToolStripDropDown control to host a ListBox inside of the ToolStripDropDown.
This may require some tweaking regarding the AutoClose behavior, but it should get you started:
First in your main form, add the following line to your ToolStripDropDropDown item
toolStripDropDownButton1.DropDown = new CustomListDropDown();
Then create a custom drop down class as follows:
public class CustomListDropDown : ToolStripDropDown
{
private ContextMenuStrip contextMenuStrip1;
private ToolStripMenuItem toolStripMenuItem1;
private ToolStripMenuItem toolStripMenuItem2;
private ToolStripMenuItem toolStripMenuItem3;
private System.ComponentModel.IContainer components;
public ListBox ListBox { get; private set; }
public CustomListDropDown()
{
InitializeComponent();
this.ListBox = new ListBox() { Width = 200, Height = 600 };
this.Items.Add(new ToolStripControlHost(this.ListBox));
this.ListBox.ContextMenuStrip = contextMenuStrip1;
this.ListBox.MouseDown += new MouseEventHandler(ListBox_MouseDown);
contextMenuStrip1.Closing += new ToolStripDropDownClosingEventHandler(contextMenuStrip1_Closing);
//add sample items
this.ListBox.Items.Add("Item1");
this.ListBox.Items.Add("Item2");
this.ListBox.Items.Add("Item3");
this.ListBox.Items.Add("Item4");
}
void contextMenuStrip1_Closing(object sender, ToolStripDropDownClosingEventArgs e)
{
this.Close();
this.AutoClose = true;
}
void ListBox_MouseDown(object sender, MouseEventArgs e)
{
this.AutoClose = false;
this.ListBox.SelectedIndex = this.ListBox.IndexFromPoint(e.Location);
}
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components);
this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem3 = new System.Windows.Forms.ToolStripMenuItem();
this.contextMenuStrip1.SuspendLayout();
this.SuspendLayout();
//
// contextMenuStrip1
//
this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.toolStripMenuItem1,
this.toolStripMenuItem2,
this.toolStripMenuItem3});
this.contextMenuStrip1.Name = "contextMenuStrip1";
//
// contextMenuStrip1.ContextMenuStrip
//
this.contextMenuStrip1.Size = new System.Drawing.Size(181, 48);
//
// toolStripMenuItem1
//
this.toolStripMenuItem1.Name = "toolStripMenuItem1";
this.toolStripMenuItem1.Size = new System.Drawing.Size(180, 22);
this.toolStripMenuItem1.Text = "toolStripMenuItem1";
//
// toolStripMenuItem2
//
this.toolStripMenuItem2.Name = "toolStripMenuItem2";
this.toolStripMenuItem2.Size = new System.Drawing.Size(180, 22);
this.toolStripMenuItem2.Text = "toolStripMenuItem2";
//
// toolStripMenuItem3
//
this.toolStripMenuItem3.Name = "toolStripMenuItem3";
this.toolStripMenuItem3.Size = new System.Drawing.Size(180, 22);
this.toolStripMenuItem3.Text = "toolStripMenuItem3";
//
// CustomListDropDown
//
this.Size = new System.Drawing.Size(2, 4);
this.contextMenuStrip1.ResumeLayout(false);
this.ResumeLayout(false);
}
}
In my tests this worked reasonably well. Let me know how it goes.
As ContextMenuStrip is derived from ToolStripDropDown, you could do this:
private ContextMenuStrip CopyToContextMenu(ToolStripMenuItem mnuItemSource)
{
var mnuContextDestination = new ContextMenuStrip();
//Move itens from ToolStripMenuItem to ContextMenuStrip
while (mnuItemSource.DropDown.Items.Count > 0)
{
mnuContextDestination.Items.Add(mnuItemSource.DropDown.Items[0]);
}
//Put ContextMenuStrip in ToolStripMenuItem using DropDown property
mnuItemSource.DropDown = mnuContextDestination;
return mnuContextDestination;
}