Dynamic Link Labels - c#

I have been reading up on dynamic link labels, and yet, I have not found my answer. In my code, I am reading off of a .csv file, with the basic setup that checks the lines and if every third one is filled, its a link. This all is in a tableLayoutPanel mind you. I'm creating the label like so:
tableLayoutPanel1.Controls.Add(new LinkLabel() { Text = "TEST",Name = count.ToString(),Tag = #"N:\reuther", Anchor = AnchorStyles.Left, AutoSize = true }, 2, 3);
The problem that I'm having, is that some of these columns could be empty, meaning I really don't know how many in total I will have at any moment. Any notes I have seen online, name the dynamic link, and then proceed to use a private function detecting that the particular link by name was clicked. I can't do that because I will never know how many links will be needed until runtime. I can(and did) in my example, name the link, is there anyway to use a generic .Click event that will detect any click, at which point I can just have it open the path by tag? Is there any other way to go around this?
Thank you.

With a little more tinkering, I solved the issue.
LinkLabel[] linkLabel = new LinkLabel[100];
linkLabel[count] = new LinkLabel();
linkLabel[count].Tag = #"N:\reuther";
linkLabel[count].Text = "Click Me";
tableLayoutPanel1.Controls.Add(linkLabel[count], 3, 4);
private void LinkedLabelClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
string filepath = ((LinkLabel)sender).Tag.ToString();
System.Diagnostics.Process.Start(filepath);
}
In this method, I created an array that stores 100 link labels. As I create them, I use a counting method to count how many links have been created. With each link, I used .Tag to set the filepath, and finally set the string filepath to the Tag, which allowed me to open it with the line afterwards. Thank you.

Related

Linking words to windows Explorer c#

Question: How can I make a list of link buttons so that when a user clicks on a link it opens it up in windows explorer.
So I have a rich text box that contains a list of all folder names and I have a list of all the folder paths. I want to be able to click on the folder name and have it linked using the path to the correct folder in windows explorer.
LinkLabel link = new LinkLabel();
link.Text = transfer2;
//link.Text = "something";
link.Name = dirName;
link.LinkClicked += new LinkLabelLinkClickedEventHandler(this.link_LinkClicked);
LinkLabel.Link data = new LinkLabel.Link();
data.LinkData = #"C:\";
link.Links.Add(data);
link.AutoSize = true;
link.Location =
this.Display_Rich_Text_Box.GetPositionFromCharIndex(this.Display_Rich_Text_Box.TextLength);
this.Display_Rich_Text_Box.Controls.Add(link);
this.Display_Rich_Text_Box.AppendText(link.Text + " ");
this.Display_Rich_Text_Box.SelectionStart = this.Display_Rich_Text_Box.TextLength;
I started with this code. I am using a foreach statement to get the folder names and path. I tried to change the name of link so it will appear to the user that they are clicking on folder A, but when you click on folder A it uses the path to open the windows explorer where the folder is from.
Any ideas or help would be greatly appreciated.
Update
I changed the code a little so now it will display, but I cant scroll down. It appears to be only on the surface as I ran something in the rich textbox and it was scrollable while the link stayed on the surface.
I also added a picture so you can see what the problem is. I scrolled a little bit so it would b easy to see.
LinkLabel link = new LinkLabel();
link.Text = dirName;
//link.Text = "something";
link.Name = transfer2;
//link.LinkClicked += new LinkLabelLinkClickedEventHandler(this.link_LinkClicked);
LinkLabel.Link data = new LinkLabel.Link();
data.LinkData = #"C:\";
link.Links.Add(data);
link.AutoSize = true;
link.Location =
this.Display_Rich_Text_Box.GetPositionFromCharIndex(this.Display_Rich_Text_Box.TextLength);
this.Display_Rich_Text_Box.Controls.Add(link);
this.Display_Rich_Text_Box.AppendText(link.Text + "\n");
this.Display_Rich_Text_Box.SelectionStart = this.Display_Rich_Text_Box.TextLength;
Update: I am trying to make essentially a list of hyperlinks so I don't think I can use linklabel as I think it is in a fixed position.
For the first part of your problem, opening Explorer, you can do this on the click event for each item in the list (or the click event of the whole list area, as I describe later):
System.Diagnostics.Process.Start("explorer.exe", "\"" + path + "\"");
(the quote/slash thing is to make sure paths with spaces work)
For the UI bits, I've never even seen LinkLabels before, so I don't know how you got on the road to that, lol! I'm not sure whether you're using WinForms or WPF but in either you'd generally want to use something like a ListBox (or a custom control that behaves/looks precisely how you want, but I'd guess you aren't ready for that). In WPF you could set the ListBox's ItemsSource to your data and DisplayMemberPath to whatever property the text comes from (if it is only strings then just don't set DisplayMemberPath). You'd then set up an event for clicking on the ListBox and respond to that by checking what item is selected and running the code above to open Explorer.
If you want to get your UI working with minimal changes, try replacing the LinkLabels with Buttons (you can style them to look like links if you want, at least in WPF) since those work the same way.

C# Winforms Help Text Change font

I have a little help pop-up that displays some text when the user presses a "?" label next to a drop-down to explain the different selections.
I did it using the Help.ShowPopup command since that seemed the easiest.
I was hoping there was a way to add different font properties to parts of the text or at least to the whole thing without having to go the direction of a CHM/HTML help-file.
Here is what I am trying to do:
private void helpLbl_Click(object sender, EventArgs e)
{
// for some reason, it ignores the 'parent' parameter
// and lays it out on the screen's coordinates
Point helpLocation = helpLbl.PointToScreen(Point.Empty);
helpLocation.Y += helpLbl.Height; // have it display underneath the control
Help.ShowPopup(this, // hosting form
#"<b>Fixed:</b>
Removes a fixed amount from the sale
<b>Percent Value:</b>
Removes a set percentage of the selected package from the sale
...", helpLocation);
I was hoping since there's the option to use an HTML document to display the help, I could use HTML tags to format what was being displayed, but it doesn't appear so. Any ideas?
Is there a way to do something like displaying a RichTextBox in the help pop-up?
Another possibility is generating a HTML document on-the-fly, but it asks for a "url" if I'm not supplying the text directly and I think that might be a little over-kill for the small amount I'm trying to do here.
You have two options. One is to use a WebBrowser Control. This natively accepts HTML and displays it. The problem with it is its kind of bloated just to use as a simple label.
Your second option is to simply create a RichTextLabel, simply like this:
public class RichTextLabel : RichTextBox
{
public RichTextLabel()
{
BorderStyle = BorderStyle.None;
}
}
Add this to your form and set the Rtf property to your RTF code. You will have to convert your HTML to RTF, which is easy if you got a program such as Microsoft Word, for example.

Get dynamically created element by ID in C# [duplicate]

I have stumbled across a problem with my asp.net form.
Within my form the end user chooses a number of textboxes to be dynamically created, this all works fine with the following code:
protected void txtAmountSubmit_Click(object sender, EventArgs e)
{
int amountOfTasks;
int.TryParse(txtAmountOfTasks.Text, out amountOfTasks);
for (int i = 0; i < amountOfTasks; i++)
{
TextBox txtAddItem = new TextBox();
txtAddItem.ID = "txtAddItem" + i;
txtAddItem.TextMode = TextBoxMode.MultiLine;
questionNine.Controls.Add(txtAddItem);
txtList.Add(txtAddItem.ID);
}
}
However this has also caused a small problem for me, later on in my form on the submit button click, I send the results to the specified person it needs to go to (using smtp email). Again this part is fine, until I am trying to retrieve the text from these dynamically created textboxes.
What I have tried
I have tried using this msdn access server controls ID method however this was not working.
I tried to add these new textboxes to a list, however I was unsure on how to update these textboxes when they have text in them. Therefore my results were returning null because of this.
I have also looked at other questions on SO such as this however they are usually for WPF or winforms, rather than my problem with asp.net (this usually isn't an issue, but I don't need to get the text from every textbox control in my page, just the ones that were dynamically created).
I have also tried changing how I call the code that I hoped would have worked:
string textboxesText = string.Join("\n", txtList.Select(x => x).ToArray());
and then in my concatenated string (email body) I would call:
textboxesText
The problem
As they are dynamically created I am finding it difficult to call them by their id for example: txtExampleID.Text, also as I have to increment the ID's by one each time (so they don't override each other) it has made things a little bit more difficult for me.
I am not asking for a code solution, I would prefer pointers in the right direction as I am still learning.
So to sum it all up: I need to get the text from my dynamically created textboxes to add it to my email body.
The issue is these text boxes need recreated in the Load event of the page, every single time, so that both events and values can be hooked back up and retrieved.
I think the most straight forward approach, in your case, would be to extend idea #1 that you had already tried. Build a List of these controls with enough information to recreate them in Load, but you need to store that List in either ViewState or Session.
ViewState["DynamicControls"] = list;
or
Session["DynamicControls"] = list;
I would use ViewState if you can because it gets destroyed when the user leaves the page.

Text areas and hyperlinks?

I have two quick, easy questions on C# in Visual Studio. First, is there anything like the label, but for an area of text in the program? I would like to have multiple lines of text in my program, but can only seem to accomplish it with a DotNetBar label with wordwrap turned on.
Second, is there any way to have a hyperlink in the middle of the text without using a link label? If I wanted to generate text like "An update is available, please visit http://example.com to download it!", is it possible to make the link clickable without having to position a link label in the middle of the text?
You can use a LinkLabel and set its LinkArea property:
//LinkArea (start index, length)
myLinkLabel.LinkArea = new LinkArea(37, 18);
myLinkLabel.Text = "An update is available, please visit http://example.com to download it!";
The above will make the http://example.com a link whilst the rest of the text in normal.
Edit to answer comment:
There are various ways of handling the link. One way is to give the link a description (the URL) and then launch the URL using Process.Start.
myLinkLabel.LinkArea = new System.Windows.Forms.LinkArea(37, 18);
myLinkLabel.LinkClicked += new LinkLabelLinkClickedEventHandler(myLinkLabel_LinkClicked);
myLinkLabel.Text = "An update is available, please visit http://example.com to download it!";
myLinkLabel.Links[0].Description = "http://example.com";
And the event handler can read the description and launch the site:
void myLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
Process.Start(e.Link.Description);
}
You may try RichTextBox control.
string text = "This is the extract of text located at http://www.google.com and http://www.yahoo.com";
richTextBox1.Text = text;
richTextBox1.ReadOnly = true;
richTextBox1.LinkClicked += (sa, ea) =>
{
System.Diagnostics.Process.Start(ea.LinkText);
};
You can use the normal label and make the AutoSize property as false.
And then adjust your width and height it will wrap by it self
I assume you are using doing a windows application, and not a web application.
In C# you can create a normal textbox by dragging and dropping it onto your form, change its property to multi-line, and make it read only. Thats what I always do.
As for adding a link to the text without a linklabel. There is a way to add links to textboxes. You can check out a pretty good tutorial at http://www.codeproject.com/KB/miscctrl/LinkTextBox.aspx/

Sql Reporting services - find item in report - on load

SQL reporting services has a little search box in the top of the report viewer. When used, it finds the search text, navigates to containing page and highlights the text on the page. My question is how can I do this when the report loads.
Currently I have a reportviewer embedded in my page. Is there a method that will find? I am using sql 2008 express and Dot Net 2
For example I send the serial number 1234 to the report so that when it opens it acts like the user searched for the text and finds it for them in the report.
Ed gave me the answer to the url part. http://server/Reportserver?/SampleReports/Product Catalog&rc:FindString=mystring but I still can't figure out the reportviewer.
Here is some of the page code:
using Microsoft.Reporting.WebForms;
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
Int32 iID = Convert.ToInt32(Request.QueryString["ID"]);
String reportsPath = ConfigurationManager.AppSettings["ReportsPath"];
String sReportName = "ReportInvoice";
reportViewer1.Reset();
reportViewer1.ProcessingMode = ProcessingMode.Remote;
reportViewer1.ShowParameterPrompts = false;
reportViewer1.ServerReport.ReportServerUrl = new Uri(ConfigurationManager.AppSettings["ReportViewerUrl"]);
reportViewer1.ServerReport.ReportServerCredentials = new ReportServerCredentials();//http://localhost/reportserver
reportViewer1.AsyncRendering = false;
ReportParameter[] reportParams = new ReportParameter[1];
reportViewer1.ServerReport.ReportPath = reportsPath + sReportName;
reportParams[0] = new ReportParameter("invoiceID", iID.ToString());
reportViewer1.ServerReport.Refresh();
}
}
Thanks in advance.
See this MSDN page (SQL 2005 version, but 2008 is the same, I believe).
I read through alot of the MSDN articles on the web based report viewer and tried several ways to fire off the search but only found this one to work:
First, in code you can set the search text box like so:
TextBox txt;
txt = (TextBox) this.ReportViewer1.Controls[1].Controls[4].Controls[0];
txt.Text = "test";
I did it in the ReportViewer's PreRender event. Position 1 in the first control list is the toolbar control, #4 is the search group control and then in that group the first control is the text box. The second number (4) could vary based on what you are showing / not showing in the toolbar. I was working with the default report viewer settings. It's a hack but it works.
Then I tried firing off the search event myself but this didn't result in the search working although it did fire off the event and with the correct information....
So here's what I did.
I created a javascript function:
<script type="text/javascript">
function OnFirstLoad() {
if (!isPostBack)
document.getElementById('ReportViewer1').ClientController.ActionHandler('Search', document.getElementById('ReportViewer1_ctl01_ctl04_ctl00').value);
}
</script>
I read the source of the .aspx page and found the text "find" and figured out what the client side call was. You will notice the ctl01 & ctl04 and ctl00 follow the same numbering as the server side code. You would need to change this to reflect your code. Again the second one (ctl04) is the one that is likely to change depending on how your toolbar is setup.
I then set the onload event for the body of the page to the javascript function:
<body onload="OnFirstLoad();">
The last trick was to only call this code the first time. So I added this to the page load event of the form code behind:
If (!IsPostBack)
ClientScript.RegisterClientScriptBlock(GetType(), "IsPostBack", "var isPostBack = false;", true);
else
ClientScript.RegisterClientScriptBlock(GetType(), "IsPostBack", "var isPostBack = true;", true);
This creates a variable that the javascript function checks. On the first go round it's false so it calls the report viewers search function, otherwise it's true and doesn't fire.
This is a pretty bad hack in my opinion and fragile. Changes of the report viewer's toolbar settings may require changes to the javascript and the code to set the text box.
I created a report that had several pages and the first hit wasn't until the third page and it went straight to it. From there the next button worked great until the end of the report.
To bad it's not as simple as the windows based report viewer or the server based report viewer. :)
Good Luck!
If you're trying to do this in a form in code behind then you need to find the report viewer object and add an event to the RenderingComplete that implements Find, so something like this:
public Report()
{
InitializeComponent();
rpViewer.RenderingComplete += new RenderingCompleteEventHandler(rpViewer_RenderingComplete);
}
void rpViewer_RenderingComplete(object sender, RenderingCompleteEventArgs e)
{
int x = rpViewer.Find("0", 1);
}
EDIT:
So, since this in a webpage you can't use the WinForms Controls, however, I was able to wire up a little less hacked version using Javascript that klabranche had used.
Here's a code behind class that adds a javascript function to the body of the html to search the report for the search text that you want:
private void SearchReport(ReportViewer rv, string SearchText)
{
TextBox txt = (TextBox)rv.Controls[1].Controls[4].Controls[0];
txt.Text = SearchText;
this.Body.Attributes.Add("onload", "javascript:document.getElementById('" + rv.ClientID +
"').ClientController.ActionHandler('Search', '" + SearchText + "');");
}
If you don't add the search text to the text box, then it won't show the search string in the text box on the report. This also only works for one report, so if you had additional reports you'd need to alter this. Also, for this to work you need to alter the body tag of your html:
<body id="Body" runat="server">
Have a textbox in your report that uses an expression for its background, set something like:
=iif(me.value = Parameters!Highlight.value, "Yellow", "White")
And of course, make a parameter called Highlight. ;)
Rob

Categories