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
}
Related
I want to build a Windows Forms App that has a menu (several labels) on it's left side which is toggled. On the right side there should be some columns i can scroll through. Jst like Excel with it's fixed rownumbers.
Is there a way to do this? Preferably an easy one.
I think you can use two panels to make the form like the picture you provided.
The following code is a code example and you can refer to it.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
ScrollBar hScrollBar1 = new HScrollBar();
private void Form1_Load(object sender, EventArgs e)
{
panel1.BorderStyle = BorderStyle.FixedSingle;
panel1.Dock = DockStyle.Left;
panel2.BorderStyle = BorderStyle.FixedSingle;
panel2.Dock = DockStyle.Fill;
hScrollBar1.Dock = DockStyle.Bottom;
hScrollBar1.Scroll += new ScrollEventHandler(hScroller_Scroll);
panel2.Controls.Add(hScrollBar1);
panel2.HorizontalScroll.Visible = false;
panel2.HorizontalScroll.Enabled = true;
}
private void hScroller_Scroll(object sender, ScrollEventArgs e)
{
panel2.HorizontalScroll.Value = e.NewValue;
}
}
The specific result:
I have a button, I put 2 other buttons inside it. I want those 2 other buttons to only appear when I enter the main button with my mouse. When I enter it, I want the 2 other buttons to be half opaque and only be fully opaque when I enter one of those 2 buttons.
These buttons are inside a FlowLayoutPanel with a background image on it.
This is how they look like:
The Buttons have a picture inside them and a text.
Here is my code:
public class MyButton : Button
{
public MyButton()
{
SetStyle(ControlStyles.StandardClick |
ControlStyles.StandardDoubleClick, true);
Text = component.ProductsName;
TextAlign = ContentAlignment.TopCenter;
ImageAlign = ContentAlignment.TopLeft;
Size = new Size(178, 75);
foreach (Button item in CustomButtons())
{
Controls.Add(item);
}
}
static Button[] CustomButtons()
{
Button delete = new Button();
delete.Location = new Point(157, 1);
delete.Size = new Size(20, 20);
delete.MouseEnter += OnMouseEnter;
delete.MouseLeave += DeleteOnMouseLeave;
Button customize = new Button();
customize.Location = new Point(delete.Left - 20, 1);
customize.Size = new Size(20, 20);
Button[] buttons = {delete, customize};
return buttons;
}
private static void DeleteOnMouseLeave(object sender, EventArgs e)
{
Button btn = (Button) sender;
btn.UseVisualStyleBackColor = true;
btn.BackColor = Color.Transparent;
}
private static void OnMouseEnter(object sender, EventArgs e)
{
Button btn = (Button) sender;
btn.UseVisualStyleBackColor = false;
btn.FlatAppearance.MouseOverBackColor = Color.FromArgb(100,
Color.Black);
}
}
I think I tried everything that came to my mind, I tried events and everything and the buttons never worked as I intended them to work.
Any help would be appreciated! Thanks! :D
it seems I solved it! I only had to set Flatstyle = FlatStyle.Flat and backColor = Color.Transparent! :D
Here is the result: exsample of output
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.
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;
// ..
}
Why cant I do this in wpf?
button1Click.Content = "Hover over me";
or
ToolTip t = new ToolTip();
t.Content = "Something helpful";
button1Click.Tooltip = t;
I populate my widow with populate buttons on initialization I then have a foreach loop that adds buttons like so:
foreach (var routedEventHandler in new RoutedEventHandler[] { button1Click, button2Click, button3_Click })`
Now in this area I apply styles to the buttons all in one go like so:
public void populateButtons()
{
double xPos;
double yPos;
Random ranNum = new Random();
foreach (var routedEventHandler in new RoutedEventHandler[] { button1Click, button2Click, button3_Click })
{
Button foo = new Button();
Style buttonStyle = Window.Resources["CurvedButton"] as Style;
int sizeValue = 100;
foo.Width = sizeValue;
foo.Height = sizeValue;
xPos = ranNum.Next(200);
yPos = ranNum.Next(250);
foo.HorizontalAlignment = HorizontalAlignment.Left;
foo.VerticalAlignment = VerticalAlignment.Top;
foo.Margin = new Thickness(xPos, yPos, 0, 0);
foo.Style = buttonStyle;
foo.Click += routedEventHandler;
LayoutRoot.Children.Add(foo);
}
}
}
}
But when I try this:
private void button3_Click(object sender, RoutedEventArgs e)
{
((Button)sender).ToolTip = t;
}
It only activates when a button is pressed? (Thanks #H.B)
However when I paste the tooltip code in my populate buttons:
Random ranNum = new Random();
foreach (var routedEventHandler in new RoutedEventHandler[] { button1Click, button2Click, button3_Click })
{
Button foo = new Button();
ToolTip t = new ToolTip();
t.Content = "Something helpful";
foo.ToolTip = t;
It works? But the problem is that doing it this way sets all buttons with the same tooltip and or button content! which I dont want, but I cant find a way around it?
So to summarize I can either set all buttons with the same tooltip message or button content within "populateButtons()" or I can only set tooltips and button content when the button has been pressed.
Is there no method possible that can add content to a named button?
Like my initial attempt:
button1Click.Content = "Home Button";
or
button1Click.ToolTip = "Hover over me";
Why on earth cant you set content and tooltips for specific buttons on initialization?
If you want to go this route then you can add a handler for Loaded event:
foo.Click += routedEventHandler;
foo.Loaded += routedEventHandler;
And then you have something like:
void button2Click(object sender, RoutedEventArgs e)
{
if (e.RoutedEvent == FrameworkElement.LoadedEvent)
{
ToolTip t = new ToolTip();
t.Content = "Something helpful";
((Button)sender).ToolTip = t;
return;
}
//Logic for handling button clicks goes here
MessageBox.Show("action 2");
}
You are not assigning the tooltip in the handler, so how should anything happen?
((Button)sender).ToolTip = t;
If I understand correctly, you want to have different "types" of buttons, each one with a different Click handler and a different Tooltip.
If that's the case, You could create different classes deriving from Button (e.g. HelpfulButton, UnhelpfulButton... choose good names please :) ) and in their constructor assign the handler and tooltip.
Then, in the main code, you could loop through the different classes and add instances of them directly to the main canvas.
Another possible option is to create different "template" buttons using commands and copy the properties from them instead of subclassing Button. Something like this:
Button helpfulTemplate = new Button { ToolTip = "blah" };
helpfulTemplate.Command = HelpfulCommand;
Button unhelpfulTemplate = new Button { ToolTip = "bloh" };
unhelpfulTemplate.Command = UnhelpfulCommand;
foreach(var template in new Button[] {helpfulTemplate, unhelpfulTemplate})
{
var newCopy = new Button();
//etc.
newCopy.ToolTip = template.ToolTip;
newCopy.Command = template.Command;
}