I have toolstrip menu with some buttons, menu is located in toolstrip container. What I am trying to accomplish is to open new form exactly at specific toolstripbutton location... This is my code. It works unless I move toolstrip menu to bottom or right side of toolstrip container...
private System.Windows.Forms.ToolStripButton rbRunMacro;
private System.Windows.Forms.ToolStrip tsMacroRecorder;
private void rbRunMacro_Click(object sender, EventArgs e)
{
Rectangle rect = this.rbRunMacro.Bounds;
Point location = PointToScreen ( new Point(this.tsMacroRecorder.Location.X + rect.X, this.tsMacroRecorder.Location.Y + rect.Y));
MacroListForm form = new MacroListForm();
form.StartPosition = FormStartPosition.Manual;
form.Location = location ;
form.Show();
}
You should get the location of rbRunMacro relative to the entire screen (see link).
form.Location = this.tsMacroRecorder.PointToScreen(rbRunMacro.Bounds.Location);
The reason we use ToolStrip.PointToScreen is that ToolStripButton does not offer the PointToScreen method. Therefore, we have to use ToolStripButton.Location to get the location of rbRunMacro relative to its parent control (see link).
Related
I need to put my progress/status window/form just below of the parent form or left/right side of the form.
It's very basic things and i know how to do that.. (the formal/basic way)..
Here is my code:
frmMain oTest;
oTest = new frmMain();
//oTest.FormBorderStyle = FormBorderStyle.None; (to make child form border/title bar less)
oTest.StartPosition = FormStartPosition.Manual;
oTest.Left = this.Left;
oTest.Top = this.Top + this.Height;
oTest.Width = this.Width;
oTest.ShowDialog();
But the problem is there is slight gap in between them.. please check the screenshot..
And if i try to set the child form border style to none, then the appearance became worse than above, though for my purpose i need to make the child form border style to none.
Here is the screenshot for that case:
Based my knowledge, it's look like windows theme/style change the visible appearance of the form look bit smaller where the original size is bit bigger than that?
so, my question is how i can make the child form same size as the parent form size regardless of the os theme?
thanks in advance
Based on my test, I reproduced your problem. I find that the form border width will affect the final result.
You could use the following code to get window border width.
int windowBorder = (this.Width - this.ClientRectangle.Width) / 2;
Completed code:
private void btnProcess_Click(object sender, EventArgs e)
{
Form1 oTest;
oTest = new Form1();
//oTest.FormBorderStyle = FormBorderStyle.None; (to make child form border/title bar less)
oTest.StartPosition = FormStartPosition.Manual;
int windowBorder = (this.Width - this.ClientRectangle.Width) / 2;
oTest.Left = this.Left;
oTest.Top = this.Top + this.Height-windowBorder;
oTest.Width = this.Width;
oTest.ShowDialog();
}
Result:
I'm wondering if it is possible somehow locate popup of ToolTip outside of application form in the fixed point over the empty desktop with MouseHover event, of course if event is useful for ToolTip, not sure. Or any other way if it is possible
I'm not asking for how to display another form as an option for this goal.
You can use either of these options:
Handle showing and hiding the ToolTip yourself. You can use MouseHover show the ToolTip in desired location and using MouseLeave hide it.
Using MoveWindow Windows API method, force the tooltip to show in a specific location instead of default location.
Option 1
You can handle MouseHover and MouseLeave event of your control(s) and show ToolTip in specific location of desktop window this way:
private void control_MouseHover(object sender, EventArgs e)
{
var control = (Control)sender;
var text = toolTip1.GetToolTip(control);
if (!string.IsNullOrEmpty(text))
toolTip1.Show(text, control, control.PointToClient(new Point(100, 100)));
}
private void control_MouseLeave(object sender, EventArgs e)
{
var control = (Control)sender;
toolTip1.Hide(control);
}
Option 2
As another option which I previously offered for align right edges of a control and ToolTip, you can set OwnerDraw property of ToolTip to true and handle Draw event of the control and use MoveWindow Windows API method to move ToolTip to desired location:
[System.Runtime.InteropServices.DllImport("User32.dll")]
static extern bool MoveWindow(IntPtr h, int x, int y, int width, int height, bool redraw);
private void toolTip1_Draw(object sender, DrawToolTipEventArgs e) {
e.DrawBackground();
e.DrawBorder();
e.DrawText();
var t = (ToolTip)sender;
var h = t.GetType().GetProperty("Handle",
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
var handle = (IntPtr)h.GetValue(t);
var location = new Point(100,100);
MoveWindow(handle, location.X, location.Y, e.Bounds.Width, e.Bounds.Height, false);
}
It sounds like ultimately what you want is a box to display some information whenever you hover over some particular items on your GUI. You also say that you want the information to display at a fixed point.
As opposed to achieving this with the tool-tip, I would do the following:
Create some fixed label or text-box to display information and put it somewhere on your Windows form.
Create a subscriber to the mouse hover event.
Based on the sender (which control you're hovering) from the mouse hover event, choose what information to display in the fixed location.
I've seen people doing this in some other programs... Take, RealTerm for example. Try it out if you want and see how it feels before you try this solution.
On the other hand, if you must do this with a tool-tip. You can choose the position using overloads of ToolTip.Show.
I have a picturebox1 -> Button -> picturebox2 all three are in a consecutive layer so which I want is that picturebox2 should be appear within the button when I debug the program.
My code is,
public Form1()
{
InitializeComponent();
picturebox2.parent = button;
picturebox.backcolor = color.transparent;
}
I am using .jpg for picturebox1 and a .png for picturebox2 but its not appearing. I mean the picture of picturebox2 should appear above the button.
You need to nest all 3 controls.
You also need to correct the Location of the nested controls or else they keep the original location, which are relative to their original parents, probably to the form, and not to their new parents!!
This should work better:
public Form1()
{
InitializeComponent();
button.Parent = picturebox;
picturebox2.Parent = button;
picturebox.BackColor = Color.Transparent;
button.Location = new Point(1,2); // or whatever you want!!
picturebox2.Location = new Point(3,4); // or whatever you want!!
}
You may also want to consider simply using the Image and/or the BackGroundImage properties of the Button..
Note: If you want your Button to let the bottom PictureBox shine through you need to not only set its Color but also it's FlatStyle to Flat!
In my C# Form I have a Label that displays a download percentage in the download event:
this.lblprg.Text = overallpercent.ToString("#0") + "%";
The Label control's BackColor property is set to be transparent and I want it to be displayed over a PictureBox. But that doesn't appear to work correctly, I see a gray background, it doesn't look transparent on top of the picture box. How can I fix this?
The Label control supports transparency well. It is just that the designer won't let you place the label correctly. The PictureBox control is not a container control so the Form becomes the parent of the label. So you see the form's background.
It is easy to fix by adding a bit of code to the form constructor. You'll need to change the label's Parent property and recalculate it's Location since it is now relative to the picture box instead of the form. Like this:
public Form1() {
InitializeComponent();
var pos = label1.Parent.PointToScreen(label1.Location);
pos = pictureBox1.PointToClient(pos);
label1.Parent = pictureBox1;
label1.Location = pos;
label1.BackColor = Color.Transparent;
}
Looks like this at runtime:
Another approach is to solve the design-time problem. That just takes an attribute. Add a reference to System.Design and add a class to your project, paste this code:
using System.ComponentModel;
using System.Windows.Forms;
using System.Windows.Forms.Design; // Add reference to System.Design
[Designer(typeof(ParentControlDesigner))]
class PictureContainer : PictureBox {}
You can just use
label1.Parent = pictureBox1;
label1.BackColor = Color.Transparent; // You can also set this in the designer, as stated by ElDoRado1239
You can draw text using TextRenderer which will draw it without background:
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
TextRenderer.DrawText(e.Graphics,
overallpercent.ToString("#0") + "%",
this.Font,
new Point(10, 10),
Color.Red);
}
When overallpercent value changes, refresh pictureBox:
pictureBox1.Refresh();
You can also use Graphics.DrawString but TextRenderer.DrawText (using GDI) is faster than DrawString (GDI+)
Also look at another answer here and DrawText reference here
For easy for your design.
You can place your label inside a panel. and set background image of panel is what every image you want. set label background is transparent
After trying most of the provided solutions without success, the following worked for me:
label1.FlatStyle = FlatStyle.Standard
label1.Parent = pictureBox1
label1.BackColor = Color.Transparent
You most likely not putting the code in the load function. the objects aren't drawn yet if you put in the form initialize section hence nothing happens.
Once the objects are drawn then the load function runs and that will make the form transparents.
private void ScreenSaverForm_Load(object sender, EventArgs e)
{
label2.FlatStyle = FlatStyle.Standard;
label2.Parent = pictureBox1;
label2.BackColor = Color.Transparent;
}
One way which works for everything, but you need to handle the position, on resize, on move etc.. is using a transparent form:
Form form = new Form();
form.FormBorderStyle = FormBorderStyle.None;
form.BackColor = Color.Black;
form.TransparencyKey = Color.Black;
form.Owner = this;
form.Controls.Add(new Label() { Text = "Hello", Left = 0, Top = 0, Font = new Font(FontFamily.GenericSerif, 20), ForeColor = Color.White });
form.Show();
Using Visual Studio with Windows Form you may apply transparency to labels or other elements by adding using System.Drawing; into Form1.Designer.cs This way you will have Transparency available from the Properties panel ( in Appearance at BackColor ). Or just edit code in Designer.cs this.label1.BackColor = System.Drawing.Color.Transparent;
For my C# Windows Form Application, I have created a flowlayoutpanel that contains several panels. Inside the panel, I have a button "Clear" for each and every single panel.
How do I write the event handler for the code for the button "Clear" such that once I have click the button, the panel would sort of be "Removed" from the flowlayoutpanel.
This is a short part of the code of the adding of panels to the flowlayoutpanel.
nFlowPanel.Controls.Add(createNotificationPanel());
nFlowPanel.Controls.Add(createNotificationPanel());
nFlowPanel.Controls.Add(createNotificationPanel());
nFlowPanel.Controls.Add(createNotificationPanelImpt());
nFlowPanel.Controls.Add(createNotificationPanelImpt());
and this is the code for the button "Clear"
Button btnClear = new Button
{
Text = "Clear",
Name = "btnClear",
Location = new Point(416, 17)
};
p.Controls.Add(btnClear);
btnClear.Click += new EventHandler(buttonClear_Click);
So what should i write in the following method to have the effect of removing e.g. the second panel that was added in the first part of code I have written?
void buttonClear_Click(object sender, EventArgs e)
{
throw new NotImplementedException();
}
EDIT
the code for creating my panel is
var p = new Panel
{
BorderStyle = BorderStyle.FixedSingle ,
Size = new Size(506,100),
Name = "notifyPanel"
};
and the code for creating my FlowLayoutPanel is
var nFlowPanel = new FlowLayoutPanel
{
FlowDirection = FlowDirection.TopDown,
WrapContents = false,
AutoScroll = true,
Size = new Size(530, 377),
Location = new Point(13, 145)
};
and the code for my button clear is
void buttonClear_Click(object sender, EventArgs e)
{
var button = (Control)sender;
var panel = button.Parent.Controls["notifyPanel"];
panel.Dispose();
}
however it gives the error
Object reference not set to an instance of an object.
on the panel.Dispose() line.
anyone can help?
The Controls.Remove() method is very dangerous, it doesn't dispose the control. Which will live on, moved to the so-called parking window, using up both Windows and managed resources. After a bit less than 10,000 times doing this it crashes your program when Windows is no longer willing to let you create any more windows.
Call the control's Dispose() method instead. That also automatically removes the control from its container.
void buttonClear_Click(object sender, EventArgs e)
{
var panel = nFlowPanel.Controls["notifyPanel"];
panel.Dispose();
}
You can do it like this:
nFlowPanel.Controls.Remove((sender as Button).Parent);
I will suggest you to use List for this. Before adding Panels in the FlowLayoutpanel, add them in the List. Then just remove the indexed panel from the flowlayoutpanel.
Panel pnlTemp = (panel)list[index];
nFlowPanel.Controls.Remove(pnlTemp);
To get the index of the button you have to add your buttons also to your list and after clicking any button, search the button in the list and get the index of the button where it is saved in the list. If my code is unclear, let me know. but I feel your task is that complex. I am not sure but this link may be of some help.
Hope it helps.