I am trying to get the Width of a StackPanel. I tried:
double width = stk_main.ActualWidth;
which gave zero and it shouldnt be. Also:
double width = stk_main.Width;
which gives NaN because width set to auto previously. So how can I get the width?
You can use sizeChanged, but it doesn't work when the stack panel you used not change size.
private void stk_main_SizeChanged(object sender, SizeChangedEventArgs e)
{
double yourWidthNow = e.NewSize.Width;
}
Hope it can give you some help...
You could attach to the Loaded event of the StackPanel as the layout pass will have completed by this point and the ActualWidth will be set.
Related
How to get the actualWidth after hide the TextBlock in Icon1 ?
Why both Width1 and Width2 are Same after hide the Label? I want the ActualWidth of the Icon1 after Hide the TextBlock(Label).
I need to do some action after changing the visibility based on ActualWidth!!
I also have one more question . i.e., Before hiding the visibility of label ,is there any way to determine the actualWidth(What will be the Width of Icon1 by Hiding label) of Icon1 ??
My Complete Project Link.
Why both Width1 and Width2 are Same after hide the Label?
If you print Width2 with debug writeline, you will find it will update when next SizeChanged, the problem is you get Width2 value before UI update, it will return previous value. please set a task delay before width2, you will get updated value 46.
await Task.Delay(100);
double width2 = icon1.ActualWidth;
Before hiding the visibility of label ,is there any way to determine the actualWidth.
As you mentioned above you could call ActualWidth property to return Width value.
Update
bool isResize; //set it as true after Label hidden.
private void Icon1_SizeChanged(object sender, SizeChangedEventArgs e)
{
if (isResize)
{
var newSize = e.NewSize;
// do your action here.
}
}
First off, the title might not make much sense. Suggestions for changing it are appreciated.
I am clicking into a TextBox that is inside a ScrollViewer. When that happens, the ScrollViewer will shrink in height (from the bottom up), it doesn't scroll at all, and some controls near the bottom of the viewport get covered up (cause the viewport is now smaller). If the TextBox gets covered up, I need to scroll such that it is still visible.
I have checked several SO questions, and none seem to capture my problem. This one is close, but I don't have a canvas to work with. Also, given my specific scenario, I cannot use Dispatcher to wait for the UI to load, and then use BringIntoView().
The TextBox's share an event, TextBox_GotFocus,
TextBox_GotFocus(object sender, RoutedEventArgs e)
{
myScrollViewer.Height = 400; //used to be 600
//if sender was in the 401-600 range, bring it into view
}
How do I scroll the ScrollViewer only if the entered TextBox is now hidden after the height change?
No thanks to the random downvote, but I managed to figure a roundabout way to do this.
TextBox_GotFocus(object sender, RoutedEventArgs e)
{
FrameworkElement element = sender as FrameworkElement;
//Get the distance from the top and bottom of the ScrollViewer
double offsetTop = element.TranslatePoint(new Point(), myScrollViewer).Y;
double offsetBottom = myScrollViewer.Height - offsetTop;
//Get total height needed to show the whole element
double height = 200 + element.Height;
//If the control would be hidden...
if (offsetBottom < height)
{
//Scroll down the difference
double change = myScrollViewer.VerticalOffset + (height - offsetBottom);
myScrollViewer.ScrollToVerticalOffset(change);
}
myScrollViewer.Height = 400; //used to be 600
}
i have the below text box control if the text in the textbox exceeds the max width then we should display tooltip.
<TextBox Name="ClientAgreementNumberHCCText"
TextAlignment="Left"
TextWrapping="NoWrap"
Text=" {Binding Text,Mode=OneWay}"/>
Note that i don't want to use the wrap of the textbox.
how can i do this?
This is possible by manually measuring the textBox with maximum size and compare the Desired Size with Actual Size. I added the following code in textChanged event of TextBox and it works fine.
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
textBox.Measure(new Size(Double.MaxValue, Double.MaxValue));
var width = textBox.DesiredSize.Width;
if (textBox.ActualWidth < width)
{
ToolTipService.SetToolTip(textBox, textBox.Text);
}
else
{
ToolTipService.SetToolTip(textBox, null);
}
}
More detail on this.
I think you want to use TextBox.GetRectFromCharacterIndex which will give you a Rect where the width is the width of your text.
You can calculate the rectangle and get the width on the fly whenever the binded text changes. You can compare the width to the width of your TextBox and see if the text is too long, and based on that set a tooltip or not. (Consider checking if you only need the width, or also need to consider paddings and margins)
here is my source: http://dedjo.blogspot.de/2007/03/text-length-measurement-it-really-easy.html
I have a panel1 with AutoScroll = true.I have to make panel1 scroll with btnUp and btnDown. So far I've made what I was asked for
private void btnUpClicked(Object sender, EventArgs e)
{
if (panel1.VerticalScroll.Value - 55 > 0)
panel1.VerticalScroll.Value -= 55;
else panel1.VerticalScroll.Value = 0;
}
private void btnDownClicked(Object sender, EventArgs e)
{
panel1.VerticalScroll.Value += 55;
}
But now I need to hide Scrollbar or make it invisible. I tried
panel1.VerticalScroll.Visible = false;
but it doesn't work. Any ideas guys?
Ok, I've done the working example of this for you. All you have to do is to change the max value depending on the total size of all the items inside your panel.
Form code:
public partial class Form1 : Form
{
private int location = 0;
public Form1()
{
InitializeComponent();
// Set position on top of your panel
pnlPanel.AutoScrollPosition = new Point(0, 0);
// Set maximum position of your panel beyond the point your panel items reach.
// You'll have to change this size depending on the total size of items for your case.
pnlPanel.VerticalScroll.Maximum = 280;
}
private void btnUp_Click(object sender, EventArgs e)
{
if (location - 20 > 0)
{
location -= 20;
pnlPanel.VerticalScroll.Value = location;
}
else
{
// If scroll position is below 0 set the position to 0 (MIN)
location = 0;
pnlPanel.AutoScrollPosition = new Point(0, location);
}
}
private void btnDown_Click(object sender, EventArgs e)
{
if (location + 20 < pnlPanel.VerticalScroll.Maximum)
{
location += 20;
pnlPanel.VerticalScroll.Value = location;
}
else
{
// If scroll position is above 280 set the position to 280 (MAX)
location = pnlPanel.VerticalScroll.Maximum;
pnlPanel.AutoScrollPosition = new Point(0, location);
}
}
}
Picture example:
You have to set AutoScroll option to False on your panel. I hope you understand what I've done and will get your panel running the way you want. Feel free to ask if you have any questions.
The Panel control takes on the duty you gave it by setting AutoScroll to true pretty serious. This always includes displaying the scrollbar gadget if it is necessary. So what you tried cannot work, hiding the vertical scrollbar forces Panel to recalculate layout since doing so altered the client area. It will of course discover that the scrollbar is required and promptly make it visible again.
The code that does this, Panel inherits it from ScrollableControl, is internal and cannot be overridden. This was intentional.
So using AutoScroll isn't going to get you anywhere. As an alternative, do keep in mind what you really want to accomplish. You simply want to move controls up and down. Easy to do, just change their Location property. That in turn is easiest to do if you put the controls on another panel, big enough to contain them. Set its AutoSize property to True. And implement you buttons' Click event handlers by simply changing that panel's Location property:
private const int ScrollIncrement = 10;
private void ScrollUpButton_Click(object sender, EventArgs e) {
int limit = 0;
panel2.Location = new Point(0,
Math.Min(limit, panel2.Location.Y + ScrollIncrement));
}
private void ScrollDownButton_Click(object sender, EventArgs e) {
int limit = panel1.ClientSize.Height - panel2.Height;
panel2.Location = new Point(0,
Math.Max(limit, panel2.Location.Y - ScrollIncrement));
}
Where panel1 is the outer panel and panel2 is the inner one that contains the controls. Be careful when you use the designer to put controls on it, it has a knack for giving them the wrong Parent. Be sure to use the View + Other Windows + Document Layout helper window so you can see this going wrong. After you filled it, set its AutoSizeMode property to GrowAndShrink so it snaps to its minimum size.
Try this:
panel.AutoScroll = true;
panel.VerticalScroll.Enabled = false;
panel.VerticalScroll.Visible = false;
Edit:
Actually when AutoScroll = true; It will take care of hscroll and vscroll automatically and you wont be able to change it. I found this on Panel.AutoScroll Property on MSDN
AutoScroll maintains the visibility of the scrollbars automatically. Therefore, setting the HScroll or VScroll property to true has no effect when AutoScroll is enabled.
You may try this to workaround this problem, I have copied it from this Link.
Behavior Observations 1:
If AutoScroll is set to true, you can't modify anything in VerticalScroll or HorizontalScroll. AutoScroll means AutoScroll; the control decides when scrollbars are visible, what the min/max is, etc. and you can't change a thing.
So if you want to customize the scrolling (e.g. hide scrollbars), you must set AutoScroll to false.
Looking at the source code for the ScrollableControl with Lutz Roeder's .NET Reflecter, you can see that if AutoScroll is set to true, it ignores your attempts to change property values within the VerticalScroll or HorizontalScroll properties such as MinValue, MaxValue, Visible etc.
Behavior Observations 2:
With AutoScroll set to false, you can change VerticalScroll.Minimum, VerticalScroll.Maximum, VerticalScroll.Visible values.
However, you cannot change VerticalScroll.Value!!! Wtf! If you set it to a non-zero value, it resets itself to zero.
Instead, you must set AutoScrollPosition = new Point( 0, desired_vertical_scroll_value );
And finally, SURPRISE, when you assign positive values, it flips them to negative values, so if you check AutoScrollPosition.X, it will be negative! Assign it positive, it comes back negative.
So yeah, if you want custom scrolling, set AutoScroll to false. Then set the VerticalScroll and HorizontalScroll properties (except Value). Then to change the scroll value, you need to set AutoScrollPosition, even though you aren't using auto scrolling! Finally, when you set the AutoScrollPosition, it will take on the opposite (i.e. negative) value that you assign to it, so if you want to retrieve the current AutoScrollPosition later, for example if you want to offset the scroll value by dragging the mouse to pan, then you need to remember to negate the value returned by AutoScrollPosition before reassigning it to AutoScrollPosition with some offset. WOW. Wtf.
One other thing, if you are trying to pan with the mouse, use the values of Cursor.Position rather than any mouse locations returned by the mouse events parameters. Scrolling the control will cause the event parameter values to be offset as well, which will cause it to start firing mouse move events complete with undesired values. Just use Cursor.Position, because it will use mouse screen coordinates as a fixed frame of reference, which is what you want when you're trying to pan/offset the scroll value.
I'm writing a program where the user should be able to write text in a TextBox. I'd like the TextBox to resize itself, so it fits to the content.
I've tried the following:
private void textBoxTitle_TextChanged(object sender, TextChangedEventArgs e)
{
System.Drawing.Font myFont = new System.Drawing.Font("Verdana", 8);
System.Drawing.SizeF mySize = e.Graphics.MeasureString("This is a test", myFont);
this.textBoxTitle.Width = (int)Math.Round(mySize.Width, 0);
}
I get an error saying that Graphics doesn't work for TextChangedEventArgs. Is there another way I can resize the TextBox?
You should try a code something like below. It has worked for me well.
private void textBox1_TextChanged(object sender, EventArgs e)
{
Size size = TextRenderer.MeasureText(textBox1.Text, textBox1.Font);
textBox1.Width = size.Width;
textBox1.Height = size.Height;
}
For more information refer to TextRenderer.MeasureText()
I am adding this answer as I do not see the fixed width aspect of a textbox being discussed in any of the other. If you have a fixed width for your textbox, and you want to adjust only its height you can do something like the following:
Something like this gives the height of the text as how it is drawn in the multiline wordwrapped textbox itself:
SizeF MessageSize = MyTextBoxControl.CreateGraphics()
.MeasureString(MyTextBoxControl.Text,
MyTextBoxControl.Font,
MyTextBoxControl.Width,
new StringFormat(0));
I am not sure what StringFormat should be but the values StringFormatFlags do not seem to apply to a default TextBox make up.
Now with MessageSize.Height you know the height of the text in the textbox.
I had the same problem and I solved it in a simpler way.
I used the AutoSize property of a Label control.. I added an invisible label to my form, set its AutoSize property True. When the I need to change the size of my TextBox I use this code:
MyLabel.Text = MyTextBox.Text;
MyTextBox.Size = MyLabel.Size;
I set the Maximum and Minimum Size of the label for better results.
Have Fun
Your binding to the wrong event, and you cannot use the graphics object in the TextChangedEventArgs object.
Try using the TextChanged event. The following snippet is working:
public Form1()
{
InitializeComponent();
this.textBox1.TextChanged += new EventHandler(textBox1_TextChanged);
}
void textBox1_TextChanged(object sender, EventArgs e)
{
System.Drawing.SizeF mySize = new System.Drawing.SizeF();
// Use the textbox font
System.Drawing.Font myFont = textBox1.Font;
using (Graphics g = this.CreateGraphics())
{
// Get the size given the string and the font
mySize = g.MeasureString(textBox1.Text, myFont);
}
// Resize the textbox
this.textBox1.Width = (int)Math.Round(mySize.Width, 0);
}
}
first, create method to Make the TextBox fit its contents.
private void AutoSizeTextBox(TextBox txt)
{
const int x_margin = 0;
const int y_margin = 2;
Size size = TextRenderer.MeasureText(txt.Text, txt.Font);
txt.ClientSize =
new Size(size.Width + x_margin, size.Height + y_margin);
}
then with the TextChanged event handler calls AutoSizeTextBox() function to make the TextBox fit its text when the text changes.
private void txtContents_TextChanged(object sender, EventArgs e)
{
AutoSizeTextBox(sender as TextBox);
}
That’s all, for more info:
resize-a-textbox-to-fit-its-text
You will need to use the CreateGraphics() method of the form to create the Graphics instance to measure the string on.
The TextChangedEventArgs class does not have a Graphics property, that is a property of the PaintEventArgs class passed in to the Paint event handler
Try this:
using System.Drawing;
...
private void textBoxTitle_TextChanged(object sender, TextChangedEventArgs e)
{
// Determine the correct size for the text box based on its text length
// get the current text box safely
TextBox tb = sender as TextBox;
if (tb == null) return;
SizeF stringSize;
// create a graphics object for this form
using(Graphics gfx = this.CreateGraphics())
{
// Get the size given the string and the font
stringSize = gfx.MeasureString(tb.Text, tb.Font);
}
// Resize the textbox
tb.Width = (int)Math.Round(stringSize.Width, 0);
}
Essentially you create your own Graphics object for the form, then measure it based on the text and font of the TextBox. The using will properly dispose the Graphics object - your previous code would have leaked horribly!
Whatever the aim is.
If the size of the textbox should be dynamically set up based on the string, which should be the text inside this box, there is no nice option.
Reasons : MeasureString uses usual string formatters as delimiters for its own width and height.
Means, carriage return and line feed are parsed, too. Resulting in a sizeF.Width and sizeF.Height.
Depending on the string( and its font and number of lines ) these both variables can carry values, which are sometimes useless to be used as width/height values of a textbox ( because they can be bigger than the parentform's values and this would resize the textbox to a size, with left and bottom borders beyond those of the parent form).
Some solutions are still available, depending on the aim, one would like to achieve.
One idea would be :
Create a textbox in designer, size = 100 X 100. enable word-wrapping.
In the OnTextChanged event handler of the textbox, we just resize the textbox's width to a value, defined by ourself (e.g. parentform.Width or another hard value ).
This would cause the word wrap to recalculate the string in the textbox and this would rearrange all the characters inside the textbox, because word wrap is enabled.
The height of the textbox could can be set hard to parentform.Height, for example.
BUT,
better : set the height dynamically,based on the Y value of the ReturnValue (Point) of the method texbox.GetPositionFromCharIndex(textbox.TextLength -1 ).
Then, with Math.Min() determine, which is smaller ( either parentform.Height or Point.Y ) , and reset the textbox size to new Size(previousDeterminedWidth, nowDeterminedHeight).
Please keep in mind ( if scrollbars are enabled ) to add about 17 pixs to Your width calculation.
Best regards
Did you try to set yourTextBox.AutoSize = true;?
This property may be hidden in the GUI designer, but you can set it in the form constructor right after InitializeComponent(); call.
Graphics.Measure string you can do o PaintEventArgs, not on TextChangedEventArgs
What I think you want is this
System.Drawing.Font myFont = new System.Drawing.Font("Verdana", 8);
Graphics graphics = this.CreateGraphics();
SizeF textSize = graphics.MeasureString("This is a test", myFont);
The problem is that you just cannot create a Graphics object by simply allocating it since it has no public constructor, so you should better go and use TextRenderer.MeasureText, as done in http://msdn.microsoft.com/en-us/library/y4xdbe66.aspx
TextRenderer is less accurate because it uses GDI and Graphics uses GDI+, so maybe you should leave a little margin on the value you get from the Width property.
Hope this helps