I'm looking to have a simple custom dialog box, like a message box, that has a label and a TextBox. If there's a simple way to do this, sorry! I'm really not well versed in the dialog stuff.
Thanks for any help, guys!
Here is how to make a small custom dialog box in Windows Mobile that looks like this:
alt text http://www.freeimagehosting.net/uploads/b8fb5421d6.jpg
Add a form to your project, and set its FormBorderStyle property to None. This allows the form to be resized and positioned, but also means it has no border or titlebar, and there's no way for the user to move it.
So you have to fake all three. The easiest way to fake the border and the title bar is to make the BackColor of your form SystemColors.WindowFrame, then put a label (where it says "Dialog" in the picture) with BackColor = SystemColors.Highlight and ForeColor = SystemColor.HighlightText (and bold the font), then put a panel with BackColor = SystemColors.Window where you see white in the picture. You have to tweak the positions and sizes of the label and the panel so you have a 1-pixel border (which is just the BackColor of your form showing through).
To enable the form to be dragged around by its fake titlebar, add this code to the form (and of course you have to wire up the events, too):
private bool _Moving = false;
private Point _Offset;
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
_Moving = true;
_Offset = new Point(e.X, e.Y);
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
if (_Moving)
{
Point newlocation = this.Location;
newlocation.X += e.X - _Offset.X;
newlocation.Y += e.Y - _Offset.Y;
this.Location = newlocation;
}
}
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
if (_Moving)
{
_Moving = false;
}
}
One other problem is that because there isn't a real titlebar, there's no way for the user to close the form. You have to add an OK (or Close) button, and put this in the button's Click event:
this.DialogResult = DialogResult.OK;
Normally you would use the mouse event on the title bar to facilitate dragging, but the label control doesn't have any mouse events. With this code you could actually grab anywhere on the form and drag it, except the panel blocks this and makes the title bar the only place to grab and drag.
My other answer has more details on getting information back from custom dialogs.
Update: actually, there's only no obvious way to close a borderless form without adding your own OK button. As long as you don't set your form's ControlBox property to False, the OK or X button in the upper right corner of the Today screen will close your dialog, even if it doesn't look like it will since it's not actually on the form.
If you want a super-simple but[t] ugly solution, you can include a reference in your project to Microsoft.VisualBasic, which lets you use the VB function InputBox like this:
string s = Microsoft.VisualBasic.Interaction.InputBox("prompt text",
"title text", "default value", 0, 0);
The dialog takes up the entire screen, but is simple to use. But is incredibly ugly, as I mentioned.
I'm assuming you basically want a custom dialog box that returns a string entered by the user. One way is to add a reference to Microsoft.VisualBasic to your project, which gives you access to the InputBox method, which is basically a message box with a text box on it. But that's no fun and I'm not sure it would work on a smartphone anyway.
To roll your own, you just add a form (named CustomDialog) to your project and drag a textbox (textBox1), a label (label1), and a button (labeled "OK") onto it.
To set the label text, add a parameter to the form's constructor like this:
public CustomDialog(string textCaption)
{
label1.Text = textCaption;
}
To expose the entered text to the caller, add this code to the form:
public override string Text
{
get
{
return textBox1.Text;
}
}
In the OK button's click event, put this code:
this.DialogResult = DialogResult.OK; // this will close the form, too
To use this dialog from your main form, you create an instance of this form, show it, check to see that the OK button was clicked, and then read its Text property (which returns what the user entered) like so:
using (CustomDialog dialog = new CustomDialog("What is your name"))
{
if (dialog.ShowDialog(this) == DialogResult.OK)
{
string enteredText = dialog.Text;
}
}
You can get fancier, but those are the basics.
Related
I have a PictureBox. I want to add automatically a LinkLabel at a specific location when the mouse hover to it. Everything's fine but I can't click on the LinkLabel as it can't stop flickering. This is my code:
private void ptbType1_MouseHover(object sender, EventArgs e)
{
PictureBox ptb = sender as PictureBox;
LinkLabel lkl = new LinkLabel();
lkl.Text = "Change Image...";
lkl.Font = new Font(lkl.Font.FontFamily, 10, FontStyle.Regular);
lkl.BackColor = SystemColors.Window;
lkl.AutoSize = false; lkl.TextAlign = ContentAlignment.MiddleCenter;
lkl.Size = new Size(120, 30); lkl.BorderStyle = BorderStyle.FixedSingle;
lkl.Location = new Point(ptb.Size.Width - 120, 5);
ptb.Controls.Add(lkl);
}
**UPDATE 10/18/2016: The idea using Tooltip to avoid LOTS OF linklabel by gzaxx suggests me to implement another way: A linklabel now has already been on the picture box, its Visible property was set False. When mouse hovers the picturebox, the label appears as Visible -> true, vice versa when mouse leaves. All remain the same: flickering makes it cannot be clicked. The MouseHover Event on the picture box, certainly, is the cause.
Any ideas? thanks for any help!
Your code have some issues. First you create A LOT of labels, each time mouse is moved by millimeter, new label is created. Second you do not attach event to link label so clicking on it does nothing. My advice would be to use Tooltip to show message when hovering over PictureBox with information "Click to change image..." and handle click event.
// should be called only once
private void AttachClickEvent(PictureBox ptb)
{
ptb.MouseClick += (s, o) =>
{
// open change dialog here
}
}
It's a straightforward solution.
Thanks for all your support, I've solved the problem. The key is
When the mouse cursor enter the linklabel, it coincidentally fire the MouseLeave_Event of the picturebox => linklabel disappears
As label vanished, the mouse cursor then enter the picturebox, so MouseHover_Event of the picturebox work => linklabel appears
---> eternal loop -> blinking
I 've dealt with it by this code to check whether the mouse cursor is in linklabel bound area, the linklabel stands still and only disappears when cursor actually get out of the picturebox:
private void ptbType1_MouseLeave(object sender, EventArgs e)
{
PictureBox ptb = sender as PictureBox;
LinkLabel lkl = ptb.Controls[0] as LinkLabel;
if (!lkl.Bounds.Contains(ptb.PointToClient(Cursor.Position)))
{
lkl.Visible = false;
}
}
Done! My 1st question on the site and i myself answer it, brilliant :))
I am using “Microsoft Visual Studio 2010” and C# language. My user interface look like this(before user click the Advance button):
If user click Advance button, I want it to show the rest of the window as shown in the picture bellow:
Can you please tell me how can have all these information hidden till the user click the Advance button? How can I have a smaller window first, as shown in the first figure. And when the user press the advance button, it will expand and show the rest.
If you can show me with details, I would really appreciate it
All WinForms controls, including the Form itself, have an AutoSize property. When set to true, it causes the control to automatically resize itself to fit its contents.
Therefore, you should place your "advanced" controls into a UserControl and add that UserControl to your form (or you can use a Panel if you're lazy). Then, when the "Advanced" button is clicked, toggle the visibility of your UserControl. The form should automatically adjust its size accordingly.
Alternatively, you could add SplitContainer to your form, which has the ability to collapse one of its two panels. The "Advanced" button would then toggle the state of the Panel2Collapsed property to expand/collapse the bottom panel.
Note: Grammatically, the caption of that button should be "Advanced", not "Advance". For an improved user experience, I recommend adding some kind of indicator that the button expands the available information on the window, rather than submitting it or opening a second window. Most "expander" buttons accomplish this using a downward-facing arrow, e.g.
You could use an image for this, or a Unicode glyph. For example, ▼, the black down-pointing triangle. Change it to an upward-pointing triangle when the panel is expanded.
1.Add a panel to bottom of your form and add all the controls that you need to display in the advanced button click.
2.change the following properties of both the panel and your form,
> AutoSize >> true
> AutoSizeMode >> GrowAndShrink
3.then in form load event you can use like following
private void Form1_Load(object sender, EventArgs e)
{
panel1.Visible = false;
}
4. then in advanced button click event
private void button1_Click_1(object sender, EventArgs e)
{
//panel1.Visible = true;
string value1 = button1.Text;
switch(value1)
{
case "Expand":
panel1.Visible = true;
break;
case "Reduce":
panel1.Visible = false;
break;
}
button1.Text = "Reduce";
if(panel1.Visible==true)
{
button1.Text = "Reduce";
}
else if(panel1.Visible==false)
{
button1.Text = "Expand";
}
}
At first set the following properties visible false
like all lebels and text boxs. then in the click event of the advanced button set all properties visible true.
OnLoad event of your first form set every control or groupbox (whichever you are using) visibility as false.
And on advance buttonclick event make its visibility true.
Code as follows:
private void FirstForm_Load(object sender, EventArgs e)
{
controlName.Visible=false;
}
private void btnAdvance_Click(object sender, EventArgs e)
{
controlName.Visible=true;
}
MSDN For Visibility Property:
http://msdn.microsoft.com/en-IN/library/system.windows.uielement.visibility.aspx
Hope its helpful.
you can simply do it like this,
1.Add a panel to bottom of your form and add all the controls that
you need to display in the advanced button click.
2.change the following properties of both the panel and your form,
> AutoSize >> true
> AutoSizeMode >> GrowAndShrink
3.then in form load event you can use like following
private void Form1_Load(object sender, EventArgs e)
{
panel1.Visible = false;
}
4. then in advanced button click event
private void button1_Click_1(object sender, EventArgs e)
{
panel1.Visible = true;
}
Hope this will help you and any other need this in future...!
I have no better way of explaining it, but I want to implement a container that only is shown after the user clicked "Advanced" or a plus sign somewhere in the dialog. I have a login form and want to add some "Advanced" settings. But they should normally out of view.
Of course, the dialog has to resize nicely to hold the extended content.
How should I go to implement such a thing. I have tried some Google searches, but can't find the right search words. Windows doesn't seem to have it by default.
as John Willemse suggested, I ended up creating the functionality myself. I added a Panel in the form that I just set visible or invisible.
In the Form's constructor (to hide it on first view):
public FrmLogin() {
InitializeComponent();
pnlAdvanced.Visible = false;
Height -= pnlAdvanced.Height;
}
Then, I added a LinkLabel with this Clicked handler:
private void linkLabel1_LinkClicked(object sender,
LinkLabelLinkClickedEventArgs e) {
if (pnlAdvanced.Visible == false) {
Height += pnlAdvanced.Height;
pnlAdvanced.Visible = true;
} else {
Height -= pnlAdvanced.Height;
pnlAdvanced.Visible = false;
}
}
Works perfectly and no extra code needed.
I am creating a Context Menu Strip once a Rich Text Box is right clicked. There are 2 options, one to change the font and one to change the background color. However, once I click one of the menu options, the Context Menu Strip doesn't close and overlays dialogs that are displayed. I know I can make it "global" and force it to close, but I would rather not. What is the best way to handle this?
// If the console is right clicked then show font options
private void rtb_console_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Right)
{
ContextMenuStrip menu = new ContextMenuStrip();
menu.Items.Add("Change Font");
menu.Items.Add("Change Background Color");
menu.Show(this, new Point(e.X, e.Y));
menu.ItemClicked += new ToolStripItemClickedEventHandler(menu_ItemClicked_ChangeFont);
}
}
// Determine whether to change the font or the font background color
void menu_ItemClicked_ChangeFont(object sender, ToolStripItemClickedEventArgs e)
{
Application.DoEvents(); // Read that this might help, but it doesn't
if (e.ClickedItem.Text == "Change Font")
{
FontDialog font = new FontDialog();
font.ShowColor = true;
font.Font = rtb_console.Font;
font.Color = rtb_console.ForeColor;
if (font.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
rtb_console.Font = font.Font;
rtb_console.ForeColor = font.Color;
}
}
else if (e.ClickedItem.Text == "Change Background Color")
{
ColorDialog color = new ColorDialog();
color.Color = rtb_console.BackColor;
if (color.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
rtb_console.BackColor = color.Color;
}
}
}
So this is what happens:
You don't want to create the ContextMenuStrip and show it manually each time. The better way to do this is to create the ContextMenuStrip once. Then assign it for the RichTextBox by assigning it to the ContextMenuStrip property of the RichTextBox. Doing this, you will no longer need to manually launch the ContextMenuStrip everytime a user clicks on it. It will occur automagically. It will also hide itself automagically in the way you would expect upon clicking on it.
Do this once and then remove your event handler for the MouseUp event:
ContextMenuStrip menu = new ContextMenuStrip();
menu.Items.Add("Change Font");
menu.Items.Add("Change Background Color");
menu.ItemClicked += new ToolStripItemClickedEventHandler(menu_ItemClicked_ChangeFont);
rtb_console.ContextStripMenu = menu;
Also, please please please don't use Application.DoEvents(); to try and force the UI to update itself. Head over to here and read the top answer. In general, if you are using Application.DoEvents(), you are doing something wrong and should considering changing your approach.
One thing you may also consider doing, but it is really just a matter of preference... If you are using Visual Studio, consider creating you ContextMenuStrip in the designer. That way, you can add your items, icons, and individual callbacks for each item very easily and visually. Just something I like to do out of pure personal preference.
In ToolStripItemClickedEventArgs just declare:
ContextMenuStrip menu = (ContextMenuStrip)(Sender)
if (e.ClickedItem.Text == "Change Font")
{
menu.hide();
/* and your code here*/...
}
I need to remove the focus from several TextBoxes. I tried using:
textBox1.Focused = false;
Its ReadOnly property value is true.
I then tried setting the focus on the form, so as to remove it from all the TextBoxes, but this also fails to work:
this.Focus();
and the function returns false when a textbox is selected.
So, how do I remove the focus from a TextBox?
You can add the following code:
this.ActiveControl = null; //this = form
Focusing on the label didn't work for me, doing something like label1.Focus() right?
the textbox still has focus when loading the form, however trying Velociraptors
answer, worked for me, setting the Form's Active control to the label like this:
private void Form1_Load(object sender, EventArgs e)
{
this.ActiveControl = label1;
}
Try disabling and enabling the textbox.
You can also set the forms activecontrol property to null like
ActiveControl = null;
Focus sets the input focus, so setting it to the form won't work because forms don't accept input. Try setting the form's ActiveControl property to a different control. You could also use Select to select a specific control or SelectNextControl to select the next control in the tab order.
Try this one:
First set up tab order.
Then in form load event we can send a tab key press programmatically to application. So that application will give focus to 1st contol in the tab order.
in form load even write this line.
SendKeys.Send("{TAB}");
This did work for me.
This post lead me to do this:
ActiveControl = null;
This allows me to capture all the keyboard input at the top level without other controls going nuts.
A simple solution would be to kill the focus, just create your own class:
public class ViewOnlyTextBox : System.Windows.Forms.TextBox {
// constants for the message sending
const int WM_SETFOCUS = 0x0007;
const int WM_KILLFOCUS = 0x0008;
protected override void WndProc(ref Message m) {
if(m.Msg == WM_SETFOCUS) m.Msg = WM_KILLFOCUS;
base.WndProc (ref m);
}
}
I've found a good alternative! It works best for me, without setting the focus on something else.
Try that:
private void richTextBox_KeyDown(object sender, KeyEventArgs e)
{
e.SuppressKeyPress = true;
}
I made this on my custom control, i done this onFocus()
this.Parent.Focus();
So if texbox focused - it instantly focus textbox parent (form, or panel...)
This is good option if you want to make this on custom control.
It seems that I don't have to set the focus to any other elements. On a Windows Phone 7 application, I've been using the Focus method to unset the Focus of a Textbox.
Giving the following command will set the focus to nothing:
void SearchBox_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
Focus();
}
}
http://msdn.microsoft.com/en-us/library/system.windows.forms.control.focus.aspx
It worked for me, but I don't know why didn't it work for you :/
//using System;
//using System.Collections.Generic;
//using System.Linq;
private void Form1_Load(object sender, EventArgs e)
{
FocusOnOtherControl(Controls.Cast<Control>(), button1);
}
private void FocusOnOtherControl<T>(IEnumerable<T> controls, Control focusOnMe) where T : Control
{
foreach (var control in controls)
{
if (control.GetType().Equals(typeof(TextBox)))
{
control.TabStop = false;
control.LostFocus += new EventHandler((object sender, EventArgs e) =>
{
focusOnMe.Focus();
});
}
}
}
The way I get around it is to place all my winform controls. I make all labels and non-selecting winform controls as tab order 0, then my first control as tab order 2 and then increment each selectable control's order by 1, so 3, 4, 5 etc...
This way, when my Winforms start up, the first TextBox doesn't have focus!
you can do this by two method
just make the "TabStop" properties of desired textbox to false now it will not focus even if you have one text field
drag two text box
make one visible on which you don't want foucus which is textbox1
make the 2nd one invisible and go to properties of that text field and select
tabindex value to 0 of textbox2
and select the tabindex of your textbox1 to 1
now it will not focus on textbox1
If all you want is the optical effect that the textbox has no blue selection all over its contents, just select no text:
textBox_Log.SelectionStart = 0;
textBox_Log.SelectionLength = 0;
textBox_Log.Select();
After this, when adding content with .Text += "...", no blue selection will be shown.
Please try set TabStop to False for your view control which is not be focused.
For eg:
txtEmpID.TabStop = false;
You can try:
textBox1.Enable = false;
using System.Windows.Input
Keyboard.ClearFocus();
Kinda late to the party in 2022, however none of the solutions here worked for me (idk why) using .Net_6.0_windows, so I've come up with this solution:
Label focusoutLabel = new Label() {
Text = "",
Name = "somegenericplaceholdernamethatwillneverbeusedinmyprogram",
Visible = false,
};
this.Controls.Add(focusoutLabel);
this.ActiveControl = focusoutLabel;
^Place this code to your Form load handler^
In the constructor of the Form or UserControl holding the TextBox write
SetStyle(ControlStyles.Selectable, false);
After the InitializeComponent();
Source: https://stackoverflow.com/a/4811938/5750078
Example:
public partial class Main : UserControl
{
public Main()
{
InitializeComponent();
SetStyle(ControlStyles.Selectable, false);
}