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();
Related
I trying to build a method to draw my form dynamically, this method receives a list of questions, from this we draw a form and show each question (label) and an option (yes/no - radio buttons).
I can add each control created before in my Forms.Controls, but when the form opens, just one question is rendered passing a list with more than 20 questions. Why? Did I forget to do something?
This method builds all my components to the form based on my list of questions.
private void BuildComponents(List<Question> properties)
{
this.propertyList = new List<System.Windows.Forms.Control>();
for (int i = 0; i < properties.Count; i++)
{
var newLabel = new System.Windows.Forms.Label
{
AutoSize = true,
Location = new System.Drawing.Point(13 + i + 5, 13),
Name = properties[i].Label,
Size = new System.Drawing.Size(699, properties[i].Description.Length),
TabIndex = i,
Text = properties[i].Description,
};
var newYesRadioButton = new System.Windows.Forms.RadioButton
{
AutoSize = true,
Location = new System.Drawing.Point(13 + i + 5, 34),
Name = "radioButton" + i + 1,
Size = new System.Drawing.Size(52, 21),
TabIndex = i + 1,
TabStop = true,
Text = "Sim",
UseVisualStyleBackColor = true
};
var newNoRadioButton = new System.Windows.Forms.RadioButton
{
AutoSize = true,
Location = new System.Drawing.Point(71 + i + 5, 34),
Name = "radioButton" + i + 2,
Size = new System.Drawing.Size(55, 21),
TabIndex = i + 1,
TabStop = true,
Text = "Não",
UseVisualStyleBackColor = true
};
propertyList.Add(newLabel);
propertyList.Add(newYesRadioButton);
propertyList.Add(newNoRadioButton);
};
}
This method initializes my form and add all properties built in this.Controls
private void InitializeComponent()
{
this.BuildComponents(questions);
foreach (var property in propertyList)
{
this.Controls.Add(property);
}
}
I would recommend you to use FlowLayoutPanel and UserControls. With FlowLayoutPanel you can put usercontrols one after another and you dont need to deal with the location property.
In addition, you should not change InitializeComponent..
Actually, you dont need to touch the code in the designer file!
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 have the following FlowDirectionPanel http://prntscr.com/aao6lt as you can see those are achievements for a poker game.When you get a new achievement a yes/no messageBox pops up and it ask's you if you want to go and check out your new acquirement if you press yes I want to be able to automatically navigate to the newly unlocked achievement which are contained in the FlowDirectionPanel which looks like in the image above. Also each achievement is contained in another panel which is children of the flowPanel if you look closer you can see that they have some outline border. I create and add the panels dynamically but they do have names which can help me to navigate to the desired panel. This is how i create them:
public void PanelForAchievements(Form currentForm, FlowLayoutPanel flp, AchivementRequirements achivement)
{
FlowLayoutPanel retFlp = flp;
string pGetAchivementName = #"pGet" + achivement.Name;
string lbAchivementName = #"lb" + achivement.Name;
string lbAchivementRewardName = #"lb" + achivement.Name + #"Reward";
string cbGetAchivementName = #"cbGet" + achivement.Name;
string pbAchivementName = #"pb" + achivement.Name;
var pGetAchivement = new Panel
{
Name = pGetAchivementName,
Size = new Size(retFlp.Width, 100),
BorderStyle = BorderStyle.FixedSingle,
};
currentForm.Controls.Add(pGetAchivement);
var lbAchivement = new Label
{
Name = lbAchivementName,
Location = new Point(pGetAchivement.Location.X, pGetAchivement.Location.Y),
Size = new Size(135, 30),
AutoSize = false,
BorderStyle = BorderStyle.FixedSingle,
Font = new Font("Microsoft Sans Serif", 10F, FontStyle.Regular, GraphicsUnit.Point, (byte)0),
Text = achivement.TitleText,
};
var lbAchivementReward = new Label
{
Name = lbAchivementRewardName,
AutoSize = true,
Top = (pGetAchivement.Height - pGetAchivement.Height) / 2,
Text = achivement.RewardLabelText,
TabIndex = 2,
BorderStyle = BorderStyle.FixedSingle,
Location = new Point(lbAchivement.Location.X, lbAchivement.Location.Y + lbAchivement.Height + 5)
};
var cbGetAchivement = new CheckBox
{
Name = cbGetAchivementName,
AutoCheck = false,
AutoSize = true,
Location = new Point(lbAchivement.Location.X + lbAchivement.Width + 10, lbAchivement.Location.Y),
TabIndex = 1,
UseVisualStyleBackColor = true
};
achivement.IsUnlocked(MainPoker.AllAchievements[achivement.EnumCasted], achivement.Requirement,cbGetAchivement);
var pbAchivement = new PictureBox
{
BorderStyle = BorderStyle.Fixed3D,
Name = pbAchivementName,
Dock = DockStyle.Right,
BackgroundImageLayout = achivement.PictureBoxImageLayout,
//Location = new Point(pGetAchivement.Right, pGetAchivement.Location.Y),
Size = new Size(145, 90),
SizeMode = PictureBoxSizeMode.Zoom,
TabIndex = 9,
TabStop = false,
Image = achivement.PackPreview,
};
pGetAchivement.Controls.Add(lbAchivement);
pGetAchivement.Controls.Add(lbAchivementReward);
pGetAchivement.Controls.Add(cbGetAchivement);
pGetAchivement.Controls.Add(pbAchivement);
retFlp.Controls.Add(pGetAchivement);
achivement.Title = lbAchivement;
achivement.RewardLabel = lbAchivementReward;
achivement.Unlocked = cbGetAchivement;
achivement.Preview = pbAchivement;
}
It's just simple code and this is how i initialize them :
public static RoyalFlush RoyalFlush = new RoyalFlush(1, new Tuple<string, int?>("Royal Card Pack", 100000));
private readonly CreatePanels _createAchivementPanels = new CreatePanels();
foreach (var achi in AchivementRequirements.AchivementList)
{
_createAchivementPanels.PanelForAchievements(this, pAchievementsCards, achi);
//im also doing other stuff here..
//pAchivementsCards is the name of the FlowDirectionPanel
}
Now by the time the yes/no messageBox is shown i already know which achievement is unlocked and also my achievements have classes as seen above public static RoyalFlush RoyalFlush and those classes have property - Name which obviously contains the name of the achievement im using this name to create respective names for each control i create from public static RoyalFlush RoyalFlushfor example :
string pGetAchivementName = #"pGet" + achivement.Name;
p stands for panel and i simply just get the current achievement name using the property achivement.Name and we end up with something like this : pRoyalFlush as a name for our panel. Now that i know the name of the panel and which achievement is being unlocked i need to navigate through my FlowDirectionPanel and find the specific panel and leave the focus there. I have no idea how to do that i will show an example with pictures of what i want if it's not clear by now :
First we unlock new achievement and we get the yes/no mbox : http://prnt.sc/aaodyr
Now we press the Yes button which will redirect us to my new form and show us the achievement FlowDirectionPanel : h.t.t.p.:/./.prntscr.com/aaofft here the program see's that the achievement for Full House is completed and it should show it in the middle of the screen with a nice border just like so : h.t.t.p.:././.prntscr.com/aaoh40
I dont have reputation to post more than 2 links so i had to put some dots in them ..
It's my first question and my native language is not English so excuse me for any mistakes I made.
you may make some foreahc loop, where you compare names, and then, when you find the control you need, scroll your flowlayoutpanel to it. For example, my flowlayoutpanel has 4 buttons, and only 2 of them are visible, and I want to scroll to button4:
foreach (Control c in flowLayoutPanel1.Controls)
{
if ((c as Button).Name == "button4")
{
(c as Button).Focus();
flowLayoutPanel1.ScrollControlIntoView(c);
break;
}
}
Hope I andrestand your question correctly.
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);
}
I am writing a custom message box that should behave pretty much like the MessageBox class in WinForms. All is good except when trying to determine the size of the form (including the label control displaying text).
I'm not sure how to determine the size since there are a number of factors involved including string length, embedded spaces and new lines in the text, and screen size.
Looking at the .NET reference source did not help either since the scaling portion seems to be implemented natively.
Any pointers would be appreciated.
You need to determine the maximum width of the message, and then figure out how much space the text wrapping takes. The TextRenderer.MeasureText function can provide this information for you:
string textMessage = "some really long message..."
int maxWidth = Screen.GetWorkingArea(this).Width - 480;
int useWidth = Math.Min(TextRenderer.MeasureText(textMessage,
Control.DefaultFont).Width, maxWidth);
useWidth = Math.Max(useWidth, 640);
int useHeight = Math.Max(64, TextRenderer.MeasureText(textMessage,
Control.DefaultFont,
new Size(useWidth, 0),
TextFormatFlags.TextBoxControl | TextFormatFlags.WordBreak)
.Height);
using (Form f = new Form()) {
f.Text = "Test Message";
f.FormBorderStyle = FormBorderStyle.FixedDialog;
f.MinimizeBox = false;
f.MaximizeBox = false;
f.StartPosition = FormStartPosition.CenterScreen;
f.ClientSize = new Size(useWidth + 8, useHeight + 8);
Label l = new Label { AutoSize = false };
l.Text = textMessage;
l.Font = Control.DefaultFont;
l.TextAlign = ContentAlignment.MiddleCenter;
l.Anchor = AnchorStyles.Left | AnchorStyles.Top |
AnchorStyles.Right | AnchorStyles.Bottom;
l.Location = new Point(4, 4);
l.Size = new Size(f.ClientSize.Width - 8, f.ClientSize.Height - 8);
f.Controls.Add(l);
f.ShowDialog(this);
}