When I click a button I want to delete that particular flowlayout panel along with the check box and the button itself.But I have no clue how to do this.
Here is my code to do this:
private static CheckBox _taskCompletionCheckBox;
public static void DisplaySingleTask(LayoutType layoutType, FlowLayoutPanel layoutPanel,TodoItem item)
{
//creates a panel
var parentPanel = new FlowLayoutPanel {Parent = layoutPanel, AutoSize = true, BorderStyle = BorderStyle.FixedSingle};
//Based on layout type, the panel's content's are determined
switch (layoutType)
{
case LayoutType.Small:
_taskCompletionCheckBox = new CheckBox {Parent = parentPanel, Dock = DockStyle.Left,Text = item.Name,AutoSize = true,BackColor = Color.Transparent};
_taskCompletionCheckBox.CheckedChanged += checkBox_CheckedChanged;
_taskCompletionCheckBox.Show();
var delBtn = new Button { Parent = parentPanel, Dock = DockStyle.Left, Size = new Size(30, _taskCompletionCheckBox.Size.Width),Image = Resources.DeleteTaskImage};
delBtn.Click += delBtn_Click;
break;
case LayoutType.Normal:
break;
case LayoutType.Full:
break;
default:
throw new ArgumentOutOfRangeException("layoutType");
}
}
static void delBtn_Click(object sender, EventArgs e)
{
//I would like to know how can I get a reference to the the flowlayout panel here so I can call the dispose() method on it.
}
If I have got your point, the FlawLayoutPanel you are looking for is parent of the button. Cast the sender parameter of the event handler to button and get it's parent.
static void delBtn_Click(object sender, EventArgs e)
{
Button button = (Button)sender;
FlowLayoutPanel panel = (FlowLayoutPanel)button.Parent;
// ..
}
Related
I have created a function that creates a new panel each time a button is pressed, alongside with a button, which should remove the entire panel when pressed.
Here is my code for creating the panels and the button :
Panel panel;
private void button1_Click(object sender, EventArgs e)
{
panel = new Panel();
panel.BackColor = Color.FromArgb(38, 38, 38);
panel.Margin = new System.Windows.Forms.Padding(10);
flowLayoutPanel1.Controls.Add(panel);
panel.Show();
Button delbutton = new Button();
delbutton.Text = "X";
flowLayoutPanel1.Controls.Add(delbutton);
delbutton.Click += new EventHandler(this.ButtonFunction_Click);
}
Considering that every panel created has this delbutton , how can i remove the panel of which delbutton button was pressed?
I tried to add this method to the button, but it removes panel randomly :
void ButtonFunction_Click (Object sender,EventArgs e)
{
foreach (Control controlObj in flowLayoutPanel1.Controls)
{
flowLayoutPanel1.Controls.Remove(controlObj);
controlObj.Dispose();
}
}
You can add the relevant Panel as a Tag property of its Button, then you can get that in the Click handler
private void button1_Click(object sender, EventArgs e)
{
var panel = new Panel
{
BackColor = Color.FromArgb(38, 38, 38),
Margin = new Padding(10),
};
flowLayoutPanel1.Controls.Add(panel);
panel.Show();
var delbutton = new Button
{
Text = "X",
Tag = panel,
};
delbutton.Click += ButtonFunction_Click;
flowLayoutPanel1.Controls.Add(delbutton);
}
private void ButtonFunction_Click(Object sender, EventArgs e)
{
var button = (Button)sender;
((Control)button.Tag).Dispose();
button.Dispose();
}
I am currently experimenting in WPF and just created a UniformGrid with 800 buttons which are created in a for loop. All buttons have their own names and share the same click event.
What I want to do now is the following: I want to click the first button (rect0) to change the color of this button and the next one (rect1).
I am totally stuck right now because everything I write into the click event refers to the button I clicked.
public MainWindow()
{
InitializeComponent();
for (int i = 0; i < 800; i++)
{
Button BTN_rect = new Button()
{
Name = "rect" + i,
Background = Brushes.White,
};
BTN_rect.Click += BTN_rect_Click;
Uniform.Children.Add(BTN_rect);
}
}
private void BTN_rect_Click(object sender, RoutedEventArgs e)
{
Button BTN_rect = sender as Button;
BTN_rect.Background = Brushes.Red;
MessageBox.Show(BTN_rect.Name);
}
There are a load of ways to do this.
I took a shortcut and put just 9 buttons in a stackpanel, otherwise the same.
public MainWindow()
{
InitializeComponent();
for (int i = 0; i < 8; i++)
{
Button BTN_rect = new Button()
{
Name = "rect" + i,
Content =Name,
Tag = i,
Background = Brushes.White,
};
BTN_rect.Click += BTN_rect_Click;
sp.Children.Add(BTN_rect);
}
}
private void BTN_rect_Click(object sender, RoutedEventArgs e)
{
Button current = sender as Button;
current.Background = Brushes.Red;
string targetName = $"rect{((int)current.Tag) + 1}";
Button nextButton = sp.Children.OfType<Button>().Where(x => x.Name == targetName).SingleOrDefault();
nextButton.Background = Brushes.Red;
}
Usually, you'd template data into repeated controls rather than add them in code, btw.
I have created a custom close image label, added it to a larger label, and added that to my panel. I have a bunch of these panels all over. I created a function to make this label collection which I then adds it to the panel. How do I create an event that closes the panel (Parent of Parent?) when a small close-style label is clicked? Here's what I have so far.
public void MakePanel1(string panel_name)
{
Panel MyPanel = new Panel();
Label TitleLabel = AddTitleLabel(panel_name);
MyPanel.Controls.Add(TitleLabel);
this.Controls.Add(MyPanel);
}
public Label AddTitleLabel(string title)
{
Label TitleLabel = new Label();
TitleLabel.Size = new Size(231, 20);
TitleLabel.BorderStyle = BorderStyle.FixedSingle;
TitleLabel.TextAlign = ContentAlignment.MiddleLeft;
TitleLabel.Text = title;
Label CloseLabel = new Label();
CloseLabel.Size = new Size(16, 16);
CloseLabel.Location = new Point(212, 2);
CloseLabel.Image = Image.FromFile(#"..\..\pics\x.png");
CloseLabel.Click += new System.EventHandler(this.DoStuffAndClosePanel);
TitleLabel.Controls.Add(CloseLabel);
return TitleLabel;
}
private void DoStuffAndClosePanel(object sender, EventArgs e)
{
// Do some stuff
// Close the panel -- sender.Close() ?????
}
thanks in advance
If you really want to do what you described you should know the panel control doesn't have a close method and you can:
private void DoStuffAndClosePanel(object sender, EventArgs e)
{
//Do Stuff
//...
//Close Panel
var parent=((Control)sender).Parent;
parent.Visible = false;
parent.Dispose();
parent = null;
}
As another option you can use a Form instead of such panel. You can hide title bar of form and use your close button instead.
For example if you want to have such form:
public class PanelForm:Form
{
protected override void WndProc(ref Message message)
{
const int WM_SYSCOMMAND = 0x0112;
const int SC_MOVE = 0xF010;
switch (message.Msg)
{
case WM_SYSCOMMAND:
int command = message.WParam.ToInt32() & 0xfff0;
if (command == SC_MOVE)
return;
break;
}
base.WndProc(ref message);
}
}
And the for showing such panel:
var f= new PanelForm();
f.TopLevel=false;
f.FormBorderStyle= System.Windows.Forms.FormBorderStyle.FixedSingle;
f.MinimizeBox=false;
f.MaximizeBox=false;
this.Controls.Add(f);
f.Show();
Or add it to a TableLayoutPanel, or FlowLayoutPanel
Another option could be using a TabControl and remove unwanted tabs.
I'm having something like this:
class MyPanel : FlowLayoutPanel
{
public MyPanel()
{
this.BackColor = Color.Red;
this.FlowDirection = System.Windows.Forms.FlowDirection.LeftToRight;
listBox = new ListBox();
editButton = new Button();
//editButton.Click += editButton_Click;
this.Controls.Add(listBox);
this.Controls.Add(editButton);
}
}
and then I'm adding it into my form dynamically. The problem is the listBox is overlapping the button. However if I try to add there 2 buttons instead of list it is working as it is supposed to - buttons are organized in 1 line from left to right. I want to reach the button to be next to the list. Can somebody advice me? Thanks
Try This Code:
class MyPanel : FlowLayoutPanel
{
public MyPanel()
{
this.BackColor = Color.Red;
this.FlowDirection = System.Windows.Forms.FlowDirection.LeftToRight;
listBox = new ListBox();
this.WrapContents = false; // Use this for control not wrapped
editButton = new Button();
this.Controls.Add(listBox);
this.Controls.Add(editButton);
}
}
Give a size to your dynamically added MyPanel object. It will solve your problem.
private void Form1_Load(object sender, EventArgs e)
{
MyPanel p = new MyPanel();
p.Size = new Size(500, 200); //give size
this.Controls.Add(p); // add to form
}
I was wondering how could I do this. I know I can use the button component but it has the little gray stuff around it when I give it a image. With image button how could I show another image for the hover effect
You want to create a button with no border but displays different images when the user hovers over it with the mouse? Here's how you can do it:
Add an ImageList control to your form at add two images, one for the button's normal appearance and one for when the mouse is hovering over.
Add your button and set the following properties:
FlatStyle = Flat
FlatAppearance.BorderColor (and maybe MouseOverBackColor & MouseDownBackColor) to your form's background color
ImageList = the ImageList you added to the form
ImageIndex to the index value of your normal image
Code the MouseHover and MouseLeave events for the button like this:
// ImageList index value for the hover image.
private void button1_MouseHover(object sender, EventArgs e) => button1.ImageIndex = 1;
// ImageList index value for the normal image.
private void button1_MouseLeave(object sender, EventArgs e) => button1.ImageIndex = 0;
I believe that will give you the visual effect you're looking for.
Small summary (Border, MouseDownBackColor, MouseOverBackColor)
FlatApperance
BorderColor = Black or what ever you want
BorderSize = can be set to 0
MouseDownBackColor = Transparent
MouseOverBackColor = Transparent
Text = none
For MouseDown:
// ImageList index value for the mouse down image.
private void button1_MouseDown(object sender, MouseEventArgs e) => button1.ImageIndex = 2;
You can assign the BackgroundImage property for the button. You can also use the OnMouseEnter and OnMouseExit events to change the background as per your request.
See BackgroundImage OnMouseEnter OnMouseLeave
I also needed an image button, but I wanted one like the ToolstripMenuButton.
With the correct borders and colors on hover.
So I made a custom control to do just that:
using System;
using System.ComponentModel;
using System.Windows.Forms;
namespace LastenBoekInfrastructure.Controls.Controls
{
[DefaultEvent("Click")]
public class ImageButton : UserControl
{
public string ToolTipText
{
get { return _bButton.ToolTipText; }
set { _bButton.ToolTipText = value; }
}
public bool CheckOnClick
{
get { return _bButton.CheckOnClick; }
set { _bButton.CheckOnClick = value; }
}
public bool DoubleClickEnabled
{
get { return _bButton.DoubleClickEnabled; }
set { _bButton.DoubleClickEnabled = value; }
}
public System.Drawing.Image Image
{
get { return _bButton.Image; }
set { _bButton.Image = value; }
}
public new event EventHandler Click;
public new event EventHandler DoubleClick;
private ToolStrip _tsMain;
private ToolStripButton _bButton;
public ImageButton()
{
InitializeComponent();
}
private void InitializeComponent()
{
var resources = new ComponentResourceManager(typeof(ImageButton));
_tsMain = new ToolStrip();
_bButton = new ToolStripButton();
_tsMain.SuspendLayout();
SuspendLayout();
//
// tsMain
//
_tsMain.BackColor = System.Drawing.Color.Transparent;
_tsMain.CanOverflow = false;
_tsMain.Dock = DockStyle.Fill;
_tsMain.GripMargin = new Padding(0);
_tsMain.GripStyle = ToolStripGripStyle.Hidden;
_tsMain.Items.AddRange(new ToolStripItem[] {
_bButton});
_tsMain.Location = new System.Drawing.Point(0, 0);
_tsMain.Name = "_tsMain";
_tsMain.Size = new System.Drawing.Size(25, 25);
_tsMain.TabIndex = 0;
_tsMain.Renderer = new ImageButtonToolStripSystemRenderer();
//
// bButton
//
_bButton.DisplayStyle = ToolStripItemDisplayStyle.Image;
_bButton.Image = ((System.Drawing.Image)(resources.GetObject("_bButton.Image")));
_bButton.ImageTransparentColor = System.Drawing.Color.Magenta;
_bButton.Name = "_bButton";
_bButton.Size = new System.Drawing.Size(23, 22);
_bButton.Click += bButton_Click;
_bButton.DoubleClick += bButton_DoubleClick;
//
// ImageButton
//
Controls.Add(_tsMain);
Name = "ImageButton";
Size = new System.Drawing.Size(25, 25);
_tsMain.ResumeLayout(false);
_tsMain.PerformLayout();
ResumeLayout(false);
PerformLayout();
}
void bButton_Click(object sender, EventArgs e)
{
if (Click != null)
{
Click(this, e);
}
}
void bButton_DoubleClick(object sender, EventArgs e)
{
if(DoubleClick != null)
{
DoubleClick(this, e);
}
}
public class ImageButtonToolStripSystemRenderer : ToolStripSystemRenderer
{
protected override void OnRenderToolStripBorder(ToolStripRenderEventArgs e)
{
//base.OnRenderToolStripBorder(e);
}
}
}
}