Good day all
Problem:
When creating the panel component, and assigning controls to it, with the
autosize = true
the width property does not change at all, the size remains the same (X:200,Y:100 like a drag 'n drop panel size)
this panel is
panel p
the panel's width changes when displayed (visually the width is different) but placing messagebox's displaying the width on designtime shows the panel with is 200.
What am I doing wrong?
public void AddMessage(position pos, string owner, string _message)
{
/// <summary>
/// Add's a label message panel to a parent panel
/// </summary>
/// <param name="pos">Use enum position, left is for message sent by you, right is message recieved.</param>
/// <param name="_message">Message to display</param>
owner += " :";
Panel p = new Panel()
{
MaximumSize = new Size(((int)Math.Round(this.Width * 0.8, 0)), int.MaxValue),
BackColor = (pos == position.left) ? Color.LightGreen : Color.LightSkyBlue,
AutoSize = false
};
Font bold = new Font(this.Font.FontFamily, float.Parse((this.Font.Size*1.1).ToString()), FontStyle.Bold);
Label O = new Label()
{
Location = new Point(_LABEL_MARGIN, _LABEL_MARGIN),
AutoSize = true,
Margin = new Padding(_LABEL_MARGIN),
MaximumSize = new Size((int)Math.Round(p.MaximumSize.Width * 0.38, 0), int.MaxValue),
Size = TextRenderer.MeasureText(owner, bold, new Size((int)Math.Round((p.MaximumSize.Width) * 0.38, 0), int.MaxValue), TextFormatFlags.EndEllipsis),
Font = bold,
Text = owner
};
MultiLineLabel l = new MultiLineLabel()
{
Location = new Point(O.Width + 5, _LABEL_MARGIN),
AutoSize = false,
Margin = new Padding(_LABEL_MARGIN),
MaximumSize = new Size(p.MaximumSize.Width - p.Margin.All, p.MaximumSize.Height - p.Margin.All),
Size = TextRenderer.MeasureText(_message, this.Font, new Size(p.MaximumSize.Width - _LABEL_MARGIN - O.Width - O.Left, int.MaxValue), TextFormatFlags.WordBreak),
Top = Top +3,
Text = _message
};
p.Controls.Add(O);
p.Controls.Add(l);
p.Location = new Point((pos == position.left) ? 10 :(this.Width - (p.Width + 10)), lastTop);
lastTop = _OBJEcT_BUFFER + p.Top + p.Height;
this.Controls.Add(p);
}
Related
Good afternoon!
Tell me, is it possible to place msgbox in the center of the panel on the form? or is it easier to create a form as a message and call it centered?
You might be able to center a MessageBox in your Panel, but it's much easier to create a custom one. This might help you, you can play around with the Location, the Size and the other properties.
var myMessageBox = new Form
{
StartPosition = FormStartPosition.Manual,
ShowInTaskbar = false,
Size = new Size(400, 180),
Location = new Point(this.Location.X + panel1.Location.X + panel1.Width / 2 - 200, this.Location.Y + panel1.Location.Y + panel1.Height / 2 - 90),
Text = "MessageBox",
ShowIcon = false,
};
Label label = new Label
{
Name = "label",
Text = "Some text.",
AutoSize = true,
MaximumSize = new Size (myMessageBox.Width - 30, myMessageBox.Height),
Location = new Point(10, 65)
};
myMessageBox.Controls.Add(label);
myMessageBox.ShowDialog();
I have a datagrid with modified column header which contain a button which shall open a popup.
This is written in code behind because of different data sources with different number of columns.
That's how it looks like:
Popups are stored in:
Dictionary<string, Popup> HeaderPopups = new Dictionary<string, Popup>();
And here the code behind:
dgMaterials.AutoGeneratingColumn += (ss, ee) =>
{
Button b = new Button() { Content = "...", Name = "btn_" + ee.PropertyName, Margin = new Thickness(3) };
b.Click += HeaderFilterButtonClick;
StackPanel stackPanel = new StackPanel() { Orientation = Orientation.Horizontal };
stackPanel.Children.Add(new TextBlock() { Text = ee.PropertyName, VerticalAlignment = VerticalAlignment.Center });
stackPanel.Children.Add(b);
ee.Column.Header = stackPanel;
Popup pop = new Popup() { Name = "pop_" + ee.PropertyName, Placement = PlacementMode.Bottom, PlacementTarget = b, StaysOpen = false, Width = 200, Margin = new Thickness(3) };
Border bord = new Border() { Background = Brushes.White, BorderBrush = Brushes.Gray, BorderThickness = new Thickness(1,1,1,1) };
pop.DataContext = bord;
HeaderPopups.Add(ee.PropertyName, pop);
StackPanel stack = new StackPanel() { Margin = new Thickness(5, 5, 5, 15) };
bord.DataContext = stack;
StackPanel stackButtons = new StackPanel() { Orientation = Orientation.Horizontal, Margin = new Thickness(0, 0, 0, 15) };
Button bAll = new Button() { Margin = new Thickness(0, 0, 0, 0), Name = "btnAll_" + ee.PropertyName };
bAll.Click += btnAllClick;
TextBlock txtAll = new TextBlock() { Text = "Select All", Foreground = Brushes.Blue, Cursor = Cursors.Hand };
bAll.Content = txtAll;
Button bNone = new Button() { Margin = new Thickness(10, 0, 0, 0), Name = "btnNone_" + ee.PropertyName };
bNone.Click += btnNoneClick;
TextBlock txtNone = new TextBlock() { Text = "Select None", Foreground = Brushes.Blue, Cursor = Cursors.Hand };
bNone.Content = txtNone;
stackButtons.Children.Add(bAll);
stackButtons.Children.Add(bNone);
ListBox list = new ListBox() { Name = "lst_" + ee.PropertyName, BorderThickness = new Thickness(0) };
stack.Children.Add(stackButtons);
stack.Children.Add(list);
};
So for each column a popup is generated and I have the popups with the keys Spec_No, Grade and Class in my HeaderPopups dictionary.
I want the appropriate popups to show up beneath the clicked button, like in the example from http://www.jarloo.com/excel-like-autofilter-in-wpf/
Look here:
My problem is to open these popups in HeaderFilterButtonClick-Event. I tried it with:
private void HeaderFilterButtonClick(object sender, RoutedEventArgs e)
{
Button b = sender as Button;
txtTest.Text += e.OriginalSource.ToString() + Environment.NewLine;
txtTest.Text += e.Source.ToString() + Environment.NewLine;
txtTest.Text += b.Name;
if (b.Name == "btn_Spec_No")
{
HeaderPopups["Spec_No"].IsOpen = true;
}
}
but it doesn't work.
Can anybody help?
Your Popup is currently empty and thus completely invisible.
You should set the Child property of it to the Border and also set the Child property of the Border to something for it to render:
Popup pop = new Popup() { ... };
Border bord = new Border() { Background = Brushes.White, BorderBrush = Brushes.Gray, BorderThickness = new Thickness(1, 1, 1, 1) };
bord.Child = new TextBlock() { Text = "some content..." };
pop.Child = bord;
The popup is opening and rendering, but it is empty, so it can't be seen.
the problem is here
Border bord = new Border() { Background = Brushes.White, BorderBrush = Brushes.Gray, BorderThickness = new Thickness(1,1,1,1) };
pop.DataContext = bord;
Datacontext is used to set Binding targets, which an empty popup has no bindings.
You need the fill the child object instead by changing the above into
Border bord = new Border() { Background = Brushes.White, BorderBrush = Brushes.Gray, BorderThickness = new Thickness(1,1,1,1) };
pop.Child = bord;
this sets the root of the popup container to ther Border object.
You will also have to do the same with the stack panel and border
StackPanel stack = new StackPanel() { Margin = new Thickness(5, 5, 5, 15) };
bord.Child = stack;
I can't change the position of label in the following code:
public static void Initialize()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var F = new Form
{
BackColor = Color.Black,
TransparencyKey = Color.Black,
Bounds = Screen.PrimaryScreen.Bounds,
FormBorderStyle = FormBorderStyle.None,
Location = new Point(0, 0),
MinimumSize = new Size(1920, 1080),
TopMost = true
};
var Summoner1 = new Label
{
AutoSize = true,
Text = "Summoner Flashs in 20",
Dock = DockStyle.Fill,
ForeColor = Color.White,
Font = new Font("Consolas", 12),
Location = new Point(0, 500)
};
var Summoner2 = new Label
{
AutoSize = true,
Text = "Test",
Dock = DockStyle.Fill,
ForeColor = Color.White,
Font = new Font("Consolas", 12),
Location = new Point(40, 20)
};
var Summoner3 = new Label
{
AutoSize = false,
Text = "Summoner Flash in 20",
Dock = DockStyle.Fill,
ForeColor = Color.White,
Font = new Font("Consolas", 12),
Location = new Point(0, 0)
};
var Summoner4 = new Label
{
AutoSize = false,
Text = "Summoner Flash in 20",
Dock = DockStyle.Fill,
ForeColor = Color.White,
Font = new Font("Consolas", 12),
Location = new Point(0, 0)
};
var Summoner5 = new Label
{
AutoSize = false,
Text = "Summoner Flash in 20",
Dock = DockStyle.Fill,
ForeColor = Color.White,
Font = new Font("Consolas", 12),
Location = new Point(0, 0)
};
F.Controls.Add(Summoner1);
F.Controls.Add(Summoner2);
Application.Run(F);
}
I have the code in there:
Location = new Point(0, 500)
but it seems to be appearing at 0, 0 regardless of what I put in there, which makes it look like only the Summoner1 label initializes, not the rest of them (I've tried just with Summoner1 and Summoner2). What's the problem with it?
Remove DockStyle.Fill. This property will expand your label to Fill the form regardless of the location you set. Filling means starting from location 0,0 through the size of the form
The same is true for the other labels. At the end the last rendered by the form engine will cover all the others
var Summoner1 = new Label
{
AutoSize = true,
Text = "Summoner Flashs in 20",
// Dock = DockStyle.Fill,
ForeColor = Color.White,
Font = new Font("Consolas", 12),
Location = new Point(0, 500)
};
I have a Windows form where I am adding a button control for each monitor attached to a computer. Naturally as the number of displays very from PC to PC, I want to automatically add a button per display and add them so they are displayed in a row.
Currently my code is as so:
foreach (var screen in Screen.AllScreens)
{
Button monitor = new Button
{
Name = "Monitor" + screen,
AutoSize = true,
Size = new Size(100, 60),
Location = new Point(12, 70),
ImageAlign = ContentAlignment.MiddleCenter,
Image = Properties.Resources.display_enabled,
TextAlign = ContentAlignment.MiddleCenter,
Font = new Font("Segoe UI", 10, FontStyle.Bold),
ForeColor = Color.White,
BackColor = Color.Transparent,
Text = screen.Bounds.Width + "x" + screen.Bounds.Height
};
monitorPanel.Controls.Add(monitor);
}
This is working however, it's simply placing each button on top of each other where there is more than one display (as I expected it would):
What I want to achieve is that each button is added, but in a row next to each other. I've tried various threads, searches on Google etc to no avail. Could anyone point me in the right direction please?
IIRC AllScreens can be indexed, so:
var padding = 5;
var buttonSize = new Size(100, 60);
for (int i = 0; i < Screen.AllScreens.Length; i++)
{
var screen = Screen.AllScreens[i];
Button monitor = new Button
{
Name = "Monitor" + screen,
AutoSize = true,
Size = buttonSize,
Location = new Point(12 + i * (buttonSize.Width + padding), 70),
ImageAlign = ContentAlignment.MiddleCenter,
Image = Properties.Resources.display_enabled,
TextAlign = ContentAlignment.MiddleCenter,
Font = new Font("Segoe UI", 10, FontStyle.Bold),
ForeColor = Color.White,
BackColor = Color.Transparent,
Text = screen.Bounds.Width + "x" + screen.Bounds.Height
};
monitorPanel.Controls.Add(monitor);
}
That ought to do it.
Advantages of this over the other answers: counter/indexer is built into the loop.
I couldn't try but shouldn't you set the Location different per button?
Location = new Point(12, 70),
to e.g.
Location = new Point(12 + (100 + gap) * screen_index, 70),
where 100 is the width of the screen
gap is the gap between two screens
and screen_index the index from left to right
You are in control of setting the position. You are actually setting it yourself:
Size = new Size(100, 60),
Location = new Point(12, 70)
I'd suggest you increase location with the size of each button, and additional padding:
Location = new Point(screenNumber * (100 + 5), 70)
Or something. Of course screenNumber is a counter you have to declare, initialize and increment upon each iteration.
I've attempted to create a custom Panel with a border around it, whose Color can be changed in order to "highlight" the Panel under certain conditions.
The Panel will also need to communicate certain information via text. For this purpose, I've added a Label to the Panel. I've tried the prescribed methods for centering the Label but for some reason it always puts it to the top-left of the Panel. I can't set the Label's Dock to Fill because that covers up the custom border that's been created. So I need to make it so that the Label fits within the border.
The Label's Anchor is set to None and its Location is
new Point((ClientSize.Width - Size.Width)/2, (ClientSize.Height - Size.Height)/2);
The code for the custom Panel is:
public class CustomPanel : Panel
{
public CustomPanel(int borderThickness, Color borderColor) : base()
{
SetStyle(ControlStyles.AllPaintingInWmPaint |
ControlStyles.UserPaint |
ControlStyles.OptimizedDoubleBuffer |
ControlStyles.ResizeRedraw, true);
BackColor = SystemColors.ActiveCaption;
BorderStyle = BorderStyle.FixedSingle;
Size = new Size(45, 45);
Margin = new Padding(0);
BorderThickness = borderThickness;
BorderColor = borderColor;
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
if (BorderStyle == BorderStyle.FixedSingle)
{
int halfThickness = BorderThickness / 2;
using (Pen p = new Pen(BorderColor, BorderThickness))
{
e.Graphics.DrawRectangle(p, new Rectangle(halfThickness,
halfThickness,
ClientSize.Width - BorderThickness, ClientSize.Height - BorderThickness));
}
}
}
public int BorderThickness { get; set; }
public Color BorderColor { get; set; }
}
And the Form code is:
private void NewPanelTest_Load(object sender, EventArgs e)
{
CustomPanel cp = new CustomPanel(3, Color.Black);
// Create new Label
Label info = new Label()
{
Size = new Size(30, 30),
Text = "Info",
Anchor = AnchorStyles.None,
TextAlign = ContentAlignment.MiddleCenter,
Enabled = false,
Font = new Font("Microsoft Sans Serif", 6),
ForeColor = Color.White,
Location = new Point(ClientSize.Width/2 - Width/2, ClientSize.Height/2 - Height/2)
};
cp.Controls.Add(info);
this.Controls.Add(cp);
}
EDIT: I've looked at similar questions asked and tried changing the Label's properties but with no results.
// Create new Label
Label info = new Label()
{
// Same code as before
// Different code
Left = (this.ClientSize.Width - Size.Width) / 2,
Top = (this.ClientSize.Height - Size.Height) / 2,
//Location = new Point(ClientSize.Width/2 - Width/2, ClientSize.Height/2 - Height/2)
};
I've also tried changing the Panel's Padding, also with no results.
Padding = new Padding(5);
EDIT: Attempt at programatically placing Label in center of Panel (yields results of X = 0, Y = 0)
// Create new Label
Label info = new Label()
{
// Same code as before (excluding "Left", "Top", and "Location")
};
int X = (info.ClientSize.Width - info.Width) / 2;
int Y = (info.ClientSize.Height - info.Height) / 2;
info.Location = new Point(X, Y);
MessageBox.Show(info.Location.ToString());
cp.Controls.Add(info);
We can achive this by simple steps
Set Label Anchor to Left and Right
Set Label AutoSize to false ;
Set Label TextAlign to MiddleCenter;
now Place label middle of panel.
int x = (panel1.Size.Width - label1.Size.Width) / 2;
label1.Location = new Point(x, label1.Location.Y);
Keep a Control vertically and horizontally at Center of Container
The most simple option is using a TableLayoutPanel with 1 column and 1 row instead of a Panel. Put the Label in it, then it's enough to set Anchor of label to None to have label always in center vertically and horizontally.
Also to paint custom borders, it's enough to handle CellPaint event of TableLayoutPanel and draw custom border:
private void tableLayoutPanel1_CellPaint(object sender, TableLayoutCellPaintEventArgs e)
{
var r = e.CellBounds;
r.Width--;
r.Height--;
e.Graphics.DrawRectangle(Pens.Red, r);
}
Hey this problem is pretty easy to solve. I assume that in the future you may have some more labels that you may have to center, so I made this function that accepts the label that you want to center and the parent panel. This code is for Visual C# Windows Forms Application. There are a few things that we have to do prior to calling this function. We need to:
Select the label and set its Anchor to left, right
Remove AutoSize
Set label TextAlign to MiddleCenter
This is the code that you need to write for our function
public void Centroid(Label label, Panel parent)
{
int x = (parent.Size.Width - label.Size.Width) / 2;
label.Location = new Point(x, label.Location.Y);
}
and to call the function you have to type: Centroid(label1, panel1);
This is assuming that you have a label named label1 & a panel named panel 1. You can substitute these values with anything as long as it is a label and a panel.
Hope this helps you :)
I did a horizontal centres alignment of a panel and a label thus:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
label1 = new System.Windows.Forms.Label();
this.SuspendLayout();
this.AutoScaleDimensions = new System.Drawing.SizeF(12F, 23F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(1401, 462);
this.Controls.Add(this.label1);
this.Font = new System.Drawing.Font("Times New Roman", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.Margin = new System.Windows.Forms.Padding(6, 5, 6, 5);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
this.PerformLayout();
int borderThickness = 5;
Color borderColor = Color.Cyan;
CustomPanel panel1 = new CustomPanel(borderThickness, borderColor);
panel1.BackColor = Color.Yellow;
panel1.Location = new Point(400, 30);
panel1.Size = new Size(300, 300);
panel1.Parent = this;
this.Controls.Add(panel1);
label1.Name = "label1";
label1.TabIndex = 0;
label1.AutoSize = true;
label1.ForeColor = Color.Black;
label1.Text = "this is the text whose center I want to align";
label1.Location = new Point(panel1.Location.X + panel1.Width / 2 - label1.Width / 2, 80);
if (this.Controls.Contains(label1))
{
label1.BringToFront();
}
}
private Label label1;
}
Since I posted the answer, I found out that in order the label to be aligned with the centre of the panel, the statement:
this.Controls.Add(label1);
MUST be located after the statement:
label1 = new Label();
and before the statement:
label1.Location = new Point(panel1.Location.X + panel1.Width / 2 - label1.Width / 2, 80);