I have this XAML:
<TextBlock TextWrapping="Wrap" Foreground="Green"
Text="This is some Green text up front. ">
<TextBlock Foreground="Blue">
This is some Blue text.
</TextBlock>
This is some Green text following the Blue text.
<Hyperlink>
<TextBlock Text="And finally, this is a Hyperlink." TextWrapping="Wrap"/>
</Hyperlink>
</TextBlock>
And I'd like to know how to replicate it procedurally in C#.
I know how to create TextBlocks in C# with something like:
TextBlock tb = new TextBlock();
tb.Text="Some text"
And I can put multiple TextBlocks together in a panel within C#. But I don't see how you go about putting TextBlocks into other TextBlocks, and TextBlocks into Hyperlinks into TextBlocks.
Are some container objects and extra TextBlock objects being created automatically, somehow? Or does the TextBlock have some methods/properties that allow it to contain the other items?
Other related questions:
1. What's the best way to add something like a Click() event to the Hyperlink?
2. Is there a way to get the blue text to wrap more cleanly? In the above XAML, as soon as the rightmost word would need to wrap, the entire block of blue text is wrapped instead.
Thanks for any illumination you can provide.
You can modify the collection of Inlines exposed via the TextBlock's Inlines property. The above XAML sample would look a little something like this:
TextBlock tb = new TextBlock
{
Text = "This is some Green text up front.",
Foreground = Brushes.Green
};
InlineCollection tbInlines = tb.Inlines;
tbInlines.Add(new Run
{
Text = "This is some Blue text.",
TextWrapping = TextWrapping.Wrap,
Foreground = Brushes.Blue
});
tbInlines.Add(new Run
{
Text = "This is some Green text following the Blue text."
});
Run hyperlinkRun = new Run("And finally, this is a Hyperlink.");
tbInlines.Add(new Hyperlink(hyperlinkRun));
As for your related questions:
1A) While it's possible to hook an event handler to every single Hyperlink instance using the RequestNavigate event on the class, that can be costly to setup and use more memory than is necessary. Instead I recommend leveraging routed events and simply hooking the RequestNavigate event at the container where all of your hyperlinks will be. You can do this like so:
myContainer.AddHandler(
Hyperlink.RequestNavigateEvent,
new RequestNavigateEventHandler(
(sender, args) =>
{
/* sender is the instance of the Hyperlink that was clicked here */
}));
2A) In your XAML example it's treating the inner TextBlock as an element that needs to be wrapped all together. If you're using my Run based approach the wrapping should be inherited from the containing text block.
I don't know about TextBlocks, but here is how you would do it in a RichTextBox. You could use a RichTextBox instead of a TextBlock.
RichTextBox rtbTest = new RichTextBox();
rtbTest.IsDocumentEnabled = true;
FlowDocument fd = new FlowDocument();
Paragraph para = new Paragraph();
Run r4 = new Run("Some Text To Show As Hyperlink");
Hyperlink h4 = new Hyperlink(r4);
h4.Foreground = Brushes.Red; //whatever color you want the HyperLink to be
// If you want the Hyperlink clickable
h4.NavigateUri = new Uri("Some URL");
h4.RequestNavigate += new RequestNavigateEventHandler(h_RequestNavigate);
// Leaving the two previous lines out will still make the Hyperlink, but it won't be clickable
// use this if you don't want an underline under the HyperLink
h4.TextDecorations = null;
para.Inlines.Add(h4);
fd.Blocks.Add(para);
rtbTest.Document = fd;
For normal text, I just used the HyperLink, but removed the two lines that made it clickable. This would give the text the color, but it wouldn't be clickable. Though it still makes the cursor change still. Though I am sure there is a property to change that also.
Related
I have a WPF app i'm working on.
There is a label on my window I use as a status window that I manage with a singleton.
How do i insert a link into that that label?
All the answers I see on this have to do with changing the XAML or the nature of the label. These solutions don't work, because literally anything can appear in this status window.
I want the link to raise a custom event when clicked.
Does anyone know how to do this?
Example of how the text uploaded to the label should operate. I need to raise an event when the hypertext formatted word is clicked:
"Inserting a link into text" is the same thing as adding a Hyperlink to the Inlines collection of a TextBlock:
TextBlock tb = new TextBlock();
var hp = new Hyperlink(new Run("error"));
hp.Click += (s, e) => { /* do something */ };
tb.Inlines.Add(new Run("There was as an "));
tb.Inlines.Add(hp);
tb.Inlines.Add(new Run(" on run"));
This is the one and only way to do this in WPF and it is very simple.
I am using a RichTextbox in my program to show multiple line strings in c sharp. I also need to add clickable control like button, label etc. I can add the control inside the RichTextBox properly by the following url below:
http://social.msdn.microsoft.com/Forums/en-US/winforms/thread/33dd0de0-1e30-4f68-a3e2-7b4b2f2170af/
Button b = new Button();
b.Text = "123";
b.Size = new Size(30, 30);
b.Location = new Point(50, 50);
b.Click += delegate(object sender, EventArgs e)
{
this.richTextBox1.Text += "123";
};
this.richTextBox1.Controls.Add(b);
But when I scroll the RichTextBox the controls do not move accordingly along with the text. Is there any way to move the controls as well with the text?
Thank you all!
This is incorrect. All you're doing with this code is adding a control into the RTB which acts as a container. It isn't part of the RTF document underneath.
You can draw buttons in there.. via the use of some Shape-Drawing RTF. I will point you to the RTF Specification on how to do that.
However, as for wiring up a click event to those RTF buttons.. I have no idea unfortunately.
(PS, you might be better off going with WPF's FlowDocument for this, which should do what you're after, but requires a bit more learning)
I'm confused with the RichTextBox control.
I have a RichTextBox control of my WinForm with a width of 100px. I want to create one dynamically and then reference the instance.
So, assuming on my Form I have a RichTextBox called rtbResult I would have thought I can do the following:
RichTextBox rtb = new RichTextBox();
rtb.Text = "Hello all";
rtb.Width = 50;
rtbResult = rtb;
When the code executes, the result is an empty RichTextBox on my page, at the original size of 100px (eg, not at width 50).
Please note, in live I'm using text highlighting and as such it must be a RichTextBox, the example above is stripped to make the question more concise.
Any ideas what I'm doing wrong?
What you did is not so different from this:
RichTextBox r1 = new RichTextBox();
r1.Text = "I am RTB #1";
Controls.Add(r1);
RichTextBox r2 = new RichTextBox();
r2.Text = "I am RTB #2";
Now on your page you have the RichTextBox named r1. If you do this:
r1 = r2;
You do not replace the control in the form with the new RichTextBox, you simply assign the same reference to the variable r1. In your form you still have the old control but both variables (r1 and r2) point to the same object.
What you may do, if you can't simply update the original RichTextBox with new values, is to delete the old one and to add the new one in the same position:
r2.Bounds = r1.Bounds;
Controls.Remove(r1);
Controls.Add(r2);
This is pretty naive, many properties may need to be copied from the old one to the new one (Dock, TabIndex and so on), moreover the order is important too so you may need to call Controls.SetChildIndex() for proper positioning (this depends on what you really have to do and how your code is).
The rtbResult is just a variable that contains a reference to the control, it's not the control itself. By putting the new control in that variable you are only changing the variable, the original control is still in the form, and the new control doesn't belong to any form so it's not visible anywhere.
You have to add the new control to the form to make it visible, for example:
somePanel.Controls.Add(rtb);
i want to show steps on how to cook something in winform c# .net as steps. Something like a set of text area would be nice but:
-> list box considers the whole string of one step as one item so user needs to scroll horizontally to view the whole step.
-> datagridview is also not suitable as i want the text to word wrapped.
i also want the user to be able to edit the step.
any suggestions of custom control would be nice.
Maybe a wizard like app would be suitable for you. AFAIK there's no native wizard control in C# but you could implement one using tabs or using one of many in the web.
A multi line text box will do the job great. just take a simple text box and do the following to it, and it will turn to a text area:
TextBox listBoxNewInput = new TextBox();
//Initialize label's property
listBoxNewInput.Multiline = true;
// Add vertical scroll bars to the TextBox control.
listBoxNewInput.ScrollBars = ScrollBars.Vertical;
// Allow the RETURN key in the TextBox control.
listBoxNewInput.AcceptsReturn = true;
// Allow the TAB key to be entered in the TextBox control.
listBoxNewInput.AcceptsTab = true;
// Set WordWrap to true to allow text to wrap to the next line.
listBoxNewInput.WordWrap = true;
listBoxNewInput.Width = 315;
listBoxNewInput.Height = 150;
listBoxNewInput.DoubleClick += new EventHandler(listBoxNewInput_DoubleClick);
flowLayoutPanel1.FlowDirection = FlowDirection.TopDown;
flowLayoutPanel1.Controls.Add(labelInput);
flowLayoutPanel1.FlowDirection = FlowDirection.TopDown;
flowLayoutPanel1.Controls.Add(list
BoxNewInput);
I want to arrange the controls in a Panel control. For example, I have four labels and four textboxs, I want to put them in a panel like a table without using the VS designer, only use the code. Does anyone do it before?
Best Regards,
C#, and use styles to control layout.
Panel pnl = new Panel();
Label lbl1 = new Label();
lbl1.Text = "1";
pnl.Controls.Add(lbl1);
TextBox tb1 = new TextBox();
pnl.Controls.Add(tb1);
Page.Controls.Add(pnl);
label
{
display: inline;
}
You could essential do the same thing Visual Studio does on the back end. Create a new control and set the properties, such as: size, name, text, and location.
I think that you can simply create a custom control that contains a label and a text box. Let's call this control LabeledTextBox. And then on your code simply add 4 instances of LabeledTextBox one after the other. This should provide the look and feel you want.