WPF - Text box that grows vertically to accommodate all text - wpf

The problem: I am not getting a textbox setting that will have a horizontally wordwrap and vertically auto grow functionality. I wish to do that by writing a code. I have written following code that creates a text box at mouse dblclick with wordwrap:
TextBox text2 = new TextBox();
text2.Width = 500;
text2.Visibility = Visibility.Visible;
text2.Focus();
text2.Height = 30;
text2.HorizontalAlignment = HorizontalAlignment.Left;
text2.VerticalAlignment = VerticalAlignment.Top;
Point p = e.GetPosition(LayoutRoot);
text2.Margin = new Thickness(p.X, p.Y, 0, 0);
LayoutRoot.Children.Add(text2);
But, textbox does not grow vertically.
Can somebody suggest me a code in C# to do exactly what I desire?

try using this
Grid grid = new Grid();
grid.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto });
grid.RowDefinitions.Add(new RowDefinition());
TextBox textBox = new TextBox() { Width = 100, TextWrapping = TextWrapping.Wrap };
textBox.SetValue(Grid.RowProperty, 0);
grid.Children.Add(textBox);
window.Content = grid;
where window is the Name assigned to Window(root).

One way to accomplish the growth you're looking for is to use a string measuring mechanism which you would run any time the text in your text box changes. Simply measure and resize your text box accordingly with any change to the contents.

Have you tried this?
text2.Height = double.NaN; // or don't set the property, but some custom styles might give a default value ..
text2.TextWrapping = TextWrapping.Wrap;
text2.MinHeight = 30; // or not if you want the styles default
instead of
text2.Height = 30;
not setting it or using double.NaN is the same as using 'Auto' in xaml.

Related

unify elements size in stackpanel

I need help in unifying size of elements in stackpanel
void MainPageLoaded(object sender, RoutedEventArgs e)
{
var random = new Random();
for (var i = 0; i < 5; i++)
{
var grid = new Grid();
var border = new Border()
{
Height = random.Next(50, 150),
Width = random.Next(50, 150),
Margin = new Thickness(10),
BorderBrush = new SolidColorBrush(Colors.White),
BorderThickness = new Thickness(1)
};
grid.Children.Add(border);
imageBoxesStackPanel.Children.Add(grid);
}
var h = imageBoxesStackPanel.Children.Max(n => n.DesiredSize.Height);
what I am trying to achieve is to find max height and max width of each grid in stackpanel and apply it to all of them. The problem is that desired size is always wrong.
You can only do this in a custom way after a measure/arrange pass, before that the sizes won't be visible.
After that (in the OnLoaded event, which you have), you can use the ActualHeight and ActualWidth of the grids.
In short:
var h = imageBoxesStackPanel.Children.Max(n => n.ActualHeight);
This is however bad for performance and will trigger another layout pass.
Remarks:
In WPF the best solution would be a SharedSizeGroup or a UniformGrid. This is not implemented in Silverlight, but there are people who have implemented it.
In WPF there is the UniformGrid to do this job, but unfortunately it's not implemented for Silverlight by default. There are several alternatives for it, e.g. this one

about RichTextBox in silverlight4 or wpf

I have dynamically added some RichTextbox in my Silverlight app.
so, I want to get the actualHeight of these different RichTextBox for set my layout
code like this:
RichTextBox content = new RichTextBox();
content.TextWrapping = TextWrapping.Wrap;
content.Width = 800;
Paragraph paragraph = new Paragraph();
paragraph.Inlines.Add(p.Content);
content.IsReadOnly = true;
content.Blocks.Add(paragraph);
content.FontSize = 14;
content.BorderThickness = new Thickness(0);
content.Name = "content" + i;
height.Add(content.ActualHeight);
But I find that the content.ActualHeight is always 0.0
So, I want to know how to get the actualheight of richtextbox.

How can I display multiple colored underlined Text in a Textbox

this code underlines all Text in the Textbox, can I underline only specific Text?
Brush brush = Brushes.Blue;
Pen pen = new Pen(brush,2);
TextBox tb1 = new TextBox();
tb1.AcceptsReturn = true;
tb1.Text = "This is a very long Text not?";
TextDecoration textDec = new TextDecoration(TextDecorationLocation.Underline,pen,1,TextDecorationUnit.Pixel,TextDecorationUnit.FontRecommended);
tb1.TextDecorations.Add(textDec);
tb1.Width = 400;
tb1.Height = 30;
this.AddChild(tb1);
The TextBox doesn't provide the ability to alter characteristics for individual characters. It's an all or none control.
The RichTextBox is the control you need.

How to format specific text in WPF?

I have this code that adds dotted lines under text in text box:
// Create an underline text decoration. Default is underline.
TextDecoration myUnderline = new TextDecoration();
// Create a linear gradient pen for the text decoration.
Pen myPen = new Pen();
myPen.Brush = new LinearGradientBrush(Colors.White, Colors.White, new Point(0, 0.5), new Point(1, 0.5));
myPen.Brush.Opacity = 0.5;
myPen.Thickness = 1.0;
myPen.DashStyle = DashStyles.Dash;
myUnderline.Pen = myPen;
myUnderline.PenThicknessUnit = TextDecorationUnit.FontRecommended;
// Set the underline decoration to a TextDecorationCollection and add it to the text block.
TextDecorationCollection myCollection = new TextDecorationCollection();
myCollection.Add(myUnderline);
PasswordSendMessage.TextDecorations = myCollection;
My problem is I need only the last 6 characters in the text to be formatted!
Any idea how can I achieve that?
Instead of setting the property on the entire TextBlock, create a TextRange for the last six characters and apply the formatting to that:
var end = PasswordSendMessage.ContentEnd;
var start = end.GetPositionAtOffset(-6) ?? PasswordSendMessage.ContentStart;
var range = new TextRange(start, end);
range.ApplyPropertyValue(Inline.TextDecorationsProperty, myCollection);
If PasswordSendMessage is a TextBox rather than a TextBlock, then you cannot use rich text like this. You can use a RichTextBox, in which case this technique will work but you will need to use PasswordSendMessage.Document.ContentEnd and PasswordSendMessage.Document.ContentStart instead of PasswordSendMessage.ContentEnd and PasswordSendMessage.ContentStart.
You could databind your text to the Inlines property of TextBox and make a converter to build the run collection with a seperate Run for the last 6 characters applying your decorations

Silverlight 2 TextBlock ignores MaxWidth

I am using Silverlight 2 to dynamically add a TextBlock to a Canvas. I set the MaxWidth of the TextBlock but it ignores this value and displays a string longer than the MaxWidth value.
TextBlock label=new TextBlock();
label.SetValue(Canvas.LeftProperty,Convert.ToDouble(x+3));
label.SetValue(Canvas.TopProperty, Convert.ToDouble(y + 1));
label.Width = DisplayWidth - 6;
label.Height = DisplayHeight - 2;
label.TextWrapping = TextWrapping.NoWrap;
label.MaxWidth = DisplayWidth-6;
label.MinWidth = DisplayWidth-6;
label.Text = this.Title;
label.Margin = new Thickness(3.0);
baseCanvas.Children.Add(label);
What do I have to do to get the TextBlock to restrict its width to a specific value? Ideally I'll add conditional ellipses too (i.e. ...).
It would seem that MaxWidth on a TextBlock is ineffectual when the TextBlock is a direct child of a Canvas. I can't quite fathom why that would be so. However the solution would be to place the TextBlock in a Border:-
TextBlock label=new TextBlock();
label.SetValue(Canvas.LeftProperty,Convert.ToDouble(x+3));
label.SetValue(Canvas.TopProperty, Convert.ToDouble(y + 1));
label.Width = DisplayWidth - 6;
label.Height = DisplayHeight - 2;
label.TextWrapping = TextWrapping.NoWrap;
label.MaxWidth = DisplayWidth-6;
label.MinWidth = DisplayWidth-6;
label.Text = this.Title;
label.Margin = new Thickness(3.0);
Border border = new Border();
border.Child = label;
baseCanvas.Children.Add(border);
The Border will honor the MaxWidth of the TextBlock but since it is given no thickness the border itself is invisible.

Resources