How to create drop down information box in C# Winforms? - c#

I want to make a button that can drop down a multi-line label or form which contains help documentation for the user.
I have searched and I can't find anything that is for C# Winforms. Do any free controls out there exist for this or will I have to create it myself?
Many thanks,
Richard

Using ToolStripControlHost and ToolStripDropDown controls can provide this for you:
private void button1_Click(object sender, EventArgs e) {
var helpInfo = new StringBuilder();
helpInfo.AppendLine("This is line one.");
helpInfo.AppendLine("This is line two.");
var textHelp = new TextBox() { Multiline = true,
ReadOnly = true,
Text = helpInfo.ToString(),
MinimumSize = new Size(100, 100)
};
var toolHost = new ToolStripControlHost(textHelp);
toolHost.Margin = new Padding(0);
var toolDrop = new ToolStripDropDown();
toolDrop.Padding = new Padding(0);
toolDrop.Items.Add(toolHost);
toolDrop.Show(button1, button1.Width, 0);
}
Result:

I think it will be a bad user experience to see a tooltip on click of a button. However, you can use this if you really want to
var b = new Button();
b.Click += (sender, args) => new ToolTip().Show("Help documentation", b.Parent, new Point(b.Location.X, b.Location.X + 10));

Related

I need to add a DataGridView to the form dynamically

private void btnShowCausali_Click(object sender, EventArgs e)
{
DataGridView Dati = new DataGridView();
Dati.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
Dati.Location = new System.Drawing.Point(120, 40);
Dati.Name = "Dati";
Dati.RowTemplate.Height = 24;
Dati.Size = new System.Drawing.Size(979, 458);
Dati.TabIndex = 1;
Dati.Visible = true;
Dati.Columns.Add("id", "ID");
Dati.Columns.Add("causaliname", "Nome Causale");
Dati.Columns.Add("Identificationcode", "Codice Identificativo");
Dati.Columns.Add("expired", "Data di Scadenza");
grpDatore.Controls.Add(Dati);
}
When I run this code the DataGridView does not appear on the form. Just in case it could create problem, the button btnShowCausali get created on the form load.
public void Form1_Load(object sender, EventArgs e)
{
Button btnShowCausali = new Button();
btnShowCausali.Text = "Causali";
btnShowCausali.Location = new Point(20, 20);
btnShowCausali.Size = new Size(120, 40);
}
By the way, I don't know why the button actually gets created but the DataGridView does not.
Your event handler btnShowCausali_Click is not attached to the button in Form1_Load. Are you sure it is called?
I also do not see adding this button to any container (Form, Panel, ...)
Your DataGridView will be added to grpDatore control (not form) so have that in mind when you set Location.
Attach event:
btnShowCausali.Click += btnShowCausali_Click;
First of all, if the button is created dynamically, add it to the UI.
Button btnShowCausali = new Button();
btnShowCausali.Text = "Causali";
btnShowCausali.Location = new Point(20, 20); // Make shure there aren't other controls in this point
btnShowCausali.Size = new Size(120, 40);
this.Controls.Add(btnShowCausali); //Adding the button to the form
Then, you have to attach an event handler for the Click event of the button. In short, you have to tell to the button what to do when it is clicked. You have two options to add an event handler for the click event:
Code: add btnShowCausali.Click += btnShowCausali_Click; after the InitializeComponent function call (in the constructor) or in the Load event of the form. Then add the function btnShowCausali_Click:
private void btnShowCausali_Click(object sender, EventArgs e)
{
DataGridView Dati = new DataGridView();
Dati.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
Dati.Location = new System.Drawing.Point(120, 40);
Dati.Name = "Dati";
Dati.RowTemplate.Height = 24;
Dati.Size = new System.Drawing.Size(979, 458);
Dati.TabIndex = 1;
Dati.Visible = true;
Dati.Columns.Add("id", "ID");
Dati.Columns.Add("causaliname", "Nome Causale");
Dati.Columns.Add("Identificationcode", "Codice Identificativo");
Dati.Columns.Add("expired", "Data di Scadenza");
grpDatore.Controls.Add(Dati); // DataGridView added to grpDatore, not form. Make shure grpDatore is visible.
}
Designer: double click on the button. Visual Studio will do the magic for you.

Passing and Storing Strings

I'm trying to pass some strings(className & classID) and store them in a different variable(classNameClicked & classIDClicked) based on what hyperlink the user clicked.
Here is my code behind(C#) for creating the hyperlinks:
TextBlock txt = new TextBlock();
txt.TextWrapping = TextWrapping.Wrap;
txt.Foreground = Brushes.Black;
txt.FontFamily = new FontFamily("Times New Roman");
txt.FontSize = 25;
txt.Margin = new Thickness(5);
TextBlock ClassID = new TextBlock();
ClassID.Visibility = Visibility.Collapsed;
ClassID.Text = classID;
Run run = new Run(className);
Hyperlink link = new Hyperlink(run);
link.Click += Link_Click;
txt.Inlines.Add(ClassID);
txt.Inlines.Add(link);
myStackPanel.Children.Add(txt);
frame.Content = myStackPanel;
I was able to pass the string from the className to classNameClicked by extracting the text from the hyperlink using the code below:
private void Link_Click(object sender, RoutedEventArgs e)
{
classNameClicked = ((sender as Hyperlink).Inlines.FirstInline as Run).Text;
classIDClicked = (sender as Textblock).Text;
Class_Page class_page = new Class_Page();
NavigationService.Navigate(class_page);
}
However, I cant seem to figure out how to extract the string from classID.
Please help.
You just have to reference the parent of your Hyperlink.
So instead of
classNameClicked = ((sender as Hyperlink).Inlines.FirstInline as Run).Text;
classIDClicked = (sender as TextBlock).Text;
you can write
Hyperlink link = sender as Hyperlink;
classNameClicked = (link.Inlines.FirstInline as Run).Text;
classIDClicked = (link.Parent as TextBlock).Inlines.OfType<Run>().First().Text;
If you don't want to use LINQ you could also write:
classIDClicked = ((link.Parent as TextBlock).Inlines.FirstInline as Run).Text;
But I have the same overall opinion as Mat in the comments. This is really ugly and MVVM would be the way to go for writing much cleaner code.
Additionally you should probably add some null checking too.
Edit as requested in the comment:
If you don't want to display the classID in your GUI then you could hide it in the Tag of the Hyperlink:
Hyperlink link = new Hyperlink(run);
link.Tag = classID;
link.Click += Link_Click;
And then just get it in your Click handler:
classIDClicked = link.Tag as string;
You don't need a hidden TextBlock for that.

Dynamic events in code

I have a radio buttons and one text box on a panel made dynamically . Now, I want to disable the text box when the second radio button is checked, means they are both connected. how can I make the event for it. I want to have the event working.
Thanks a lot in advanced.
this is my code which is not working:
Panel pnl = new Panel();
pnl.Name = "pnl_";
pnl.Size = new Size(630, 80);
RadioButton rd = new RadioButton();
rd.Name = "rd_" + dr[i]["Value_Name"].ToString();
rd.Text = dr[i]["Value_Name"].ToString();
rd.Location = new Point(i,i*2);
pnl.Controls.Add(rd);
TextBox txt = new TextBox();
txt.Name = "txt_" + Field_Name+"_"+dr[i]["Value_Name"].ToString();
txt.Size = new Size(171, 20);
txt.Text = Field_Name + "_" + dr[i]["Value_Name"].ToString();
txt.Location = new Point(20, 30);
pnl.Controls.Add(txt);
////// ???? ////////
rd.CheckedChanged += new EventHandler(eventTxt(txt));
void eventTxt(object sender,EventArgs e,TextBox txt)
{
RadioButton rd = (RadioButton)sender;
txt.Enabled = rd.Checked;
}
Use a lambda to close over the relevant variable(s):
rd.CheckedChanged += (s, args) => txt.Enabled = rd.Checked;
If you had more than a one line implementation, you could call out to a method accepting whatever parameters you've closed over, instead of including it all inline.
I would suggest to set the Tag of the radio button and get walk down the dependencies.
rd.Tag = txt;
In the event handler use this:
TextBox txt = (sender as Control).Tag as TextBox;
txt.Enabled = ...
you can use code given
rd.CheckedChanged += (s,argx) => txt.Enabled = rd.Checked;
Here's how you could create an event for it:
//if you are using Microsoft Visual Studio, the following
//line of code will go in a separate file called 'Form1.Design.cs'
//instead of just 'Form1.cs'
myTextBox.CheckChangedEventHandeler += new EventHandeler(checkBox1_CheckChanged); //set an event handeler
public void checkBox1_CheckChanged(object sender, EventArgs e) //what you want to happen every time the check is changed
{
if(checkBox1.checked == true) //replace 'checkBox1' with your check-box's name
{
myTextBox.enabled = false; //replace 'myTextbox' with your text box's name;
//change your text box's enabled property to false
}
}
Hope it helps!

Show a link to a path in a message form in c#

I have a desktop application in C# .In this I have a form in which I show different messages .
I have one message who say : "The output file was generated in : C:\Work\result.txt".
How can I show this path to the file as a link and when the form with this message is shown to see the path as a link and when the user click the link to open the specified path/file?
I tried :
The output file was generated in : C:\Work\result.txt
But doesn't work.
Thanks !
You can have an event for on-onclick, and then you can open file using the below code.
System.Diagnostics.Process.Start(#"C:\Work\result.txt"); //or like
System.Diagnostics.Process.Start(#"C:\Work\result.docx");
Here, the default program must be there for the file. Then only shell will run associated program reading it from the registry, like usual double click does in explorer.
MessageBox.Show() method takes the caption, text, icon, buttons and default button of the dialog.However there's nothing mentioned in the .NET Framework documentation that says anything about adding links to a MessageBox
However, you can do the effect you want by creating a new class inherited from System.Windows.Forms.Form and add a button (or more if you like), an icon, a label and a LinkButton. Then use the ShowDialog() Method of the Form class to display the message box in modal form. You may also create a class called MyErrorBox (static class in C# 2 or just sealed in C# 1) that contains only one static method called Show() which creates a form, adds the needed controls and displays the form in modal mode. A demonstration of the last method is shown below. Then you can use this class whenever you want and wherever you please!
using System;
using System.Windows.Forms;
using System.Drawing;
namespace MessageBoxes{
public sealed class MyErrorBox{
private MyErrorBox(){}
private static Form frm;
private static string detailsStore;
private static TextBox txt;
public static DialogResult Show(string caption, string text, string details, Icon icon){
frm = new Form(); frm.Size = new Size(510, 195);
frm.Text = caption; frm.ShowInTaskbar = false; frm.ControlBox = false;
frm.FormBorderStyle = FormBorderStyle.FixedDialog;
PictureBox icon1 = new PictureBox(); icon1.Location = new Point(8,16);
icon1.Size = new Size(icon.Width, icon.Height);
icon1.Image = icon.ToBitmap();
frm.Controls.Add(icon1);
Label lbl = new Label(); lbl.Text = text; lbl.Location = new Point(88,8);
lbl.Size = new Size(400,88); frm.Controls.Add(lbl);
LinkLabel btn1 = new LinkLabel(); btn1.Text = "View Details";
btn1.Size = new Size(72,23); btn1.Location = new Point(416,96);
btn1.Click += new EventHandler(btn1_Click); frm.Controls.Add(btn1);
//Ofcourse you can add more buttons than just the ok with more DialogResults
Button btn2 = new Button(); btn2.Text = "&Ok";
btn2.Size = new Size(72,23); btn2.Location = new Point(224,130);
btn2.Anchor = AnchorStyles.Bottom; frm.Controls.Add(btn2);
frm.AcceptButton = btn2; btn2.Click += new EventHandler(btn2_Click);
btn2.DialogResult = DialogResult.OK; detailsStore = details;
return frm.ShowDialog();
}
private static void btn1_Click(object sender, EventArgs e) {
frm.Size = new Size(510,320);
txt = new TextBox(); txt.Multiline = true;
txt.ScrollBars = ScrollBars.Both; txt.Text = detailsStore;
txt.Size = new Size(488,128); txt.Location = new Point(8,120);
txt.ReadOnly = true; frm.Controls.Add(txt);
LinkLabel lnk = (LinkLabel)(sender); lnk.Text = "Hide Details";
lnk.Click -= new EventHandler(btn1_Click);
lnk.Click += new EventHandler(btn1_ReClick);
}
private static void btn2_Click(object sender, EventArgs e) {
frm.Close();
}
private static void btn1_ReClick(object sender, EventArgs e) {
frm.Controls.Remove(txt); frm.Size = new Size(510, 195);
LinkLabel lnk = (LinkLabel)(sender); lnk.Text = "View Details";
lnk.Click -= new EventHandler(btn1_ReClick);
lnk.Click += new EventHandler(btn1_Click);
}
}
}
There's no standard MessageBox functionality that'll be able to do this via link label. What I suggest is you use the Yes/No Messagebox buttons and from the option selected you then apply an event
Something like this:
if (MessageBox.Show(
"The file is saved at the following link: link here", "Success", MessageBoxButtons.YesNo, MessageBoxIcon.Asterisk
) == DialogResult.Yes)
{
System.Diagnostics.Process.Start(#"C:\TestLocation\SavedFiles");
}

Create dynamic dragpanel in asp.net with c#

I want to create ajax dragpanel dynamically and add the controls and panel dynamically.I used the below code for create the control dynamically.But I can`t able to drag it.
enter code here
protected void Page_PreInit(object sender, EventArgs e)
{
DragPanelExtender drg = new DragPanelExtender();
drg.ID = "drg_1";
drg.DragHandleID = "pnl_1";
drg.TargetControlID = "pnl_2";
Panel p1 = new Panel();
p1.ID = "pnl_1";
Panel p2 = new Panel();
p2.ID = "pnl_2";
Label l1 = new Label();
l1.Text = "First";
TextBox t = new TextBox();
t.Text = "Enter text";
p2.Controls.Add(l1);
p2.Controls.Add(t);
p1.Controls.Add(p2);
Page.Controls.Add(p1);
}
How to I create drag controls inside the panel

Categories