How can I get the height of a ListView item? - c#

I have ListView and I need to determine item height.

You can use the GetItemRect() method:
int itemHeight = yourListView.GetItemRect(itemIndex).Height;

I am not 100% sure but this might help:
int itemHeight = listView.Items[itemIndex].GetBounds(ItemBoundsPortion.Entire).Height;

I had the same question however there is one issue - until the listview is drawn the values aren't set. And you may want to be able to set the sizes before you add any items (if for example I want to dry a listview that can display 5 entries but will start off empty).
Therefore my workaround was to run the following code, which forces the control to be rendered but without displaying it, in the application's initialisation section and save the values as global variables for later use. And, to get around listviews with different font sizes, to only store the difference between the height and the font height:
Dim lvwTemp As New ListView
lvwTemp.View = View.Details
lvwTemp.Columns.Add("test")
lvwTemp.Items.Add("test")
Dim zTempBitmap As New Bitmap(100, 100)
lvwTemp.DrawToBitmap(zTempBitmap, New Rectangle(0, 0, 100, 100))
zTempBitmap.Dispose()
gintListviewHeaderHeightMinusFontSize = lvwTemp.Items(0).GetBounds(ItemBoundsPortion.Entire).Top - lvwTemp.Font.Height
gintListviewItemHeightMinusFontSize = lvwTemp.Items(0).GetBounds(ItemBoundsPortion.Entire).Height - lvwTemp.Font.Height

Related

Setting the DataGridView AllowUserToResizeColumns is not 100% correct

If I set a the DataGridView to:
dataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
dataGridView.AllowUserToAddRows = false;
dataGridView.AllowUserToResizeColumns = false;
And then set my columns like this:
dataGridView.Columns["Colour"].FillWeight = 50;
dataGridView.Columns["Layer"].FillWeight = 50;
cboColumn.DefaultCellStyle.Padding = new Padding(16, 0, 16, 0);
It initially looks great:
I purposely put the mouse over the column resize and it won't allow. Good! But ...
I can still resize the column on the left, and when I do that, my painting on the right looks bad:
So I have two issues here:
Why is it that I can still resize the first column? I don't want to allow it.
If it must be allowed, can we deal with the last column issue?
Thoughts?
To have fixed row header width and prevent users from resizing row header width, you can set RowHeadersWidthSizeMode property of your grid to DisableResizing using designer or code:
grid.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.DisableResizing;
This way the size of row headers would be the fixed value which you set using RowHeadersWidth property of your data grid view control.
You can also use auto size options of DataGridViewRowHeadersWidthSizeMode enumeration.
By default, users can resize the width of the row headers. You can
disable this ability to set a fixed width, or you can use a
content-based automatic sizing mode, which also disables user
resizing.

How do you calculate pixel size of string?

I have a string. I know the font family and the font size it is going to be displayed in. I need to know how many pixels the text will take up in the ui. So that I can determine whether to show another element. How would I do that?
I found a couple of things, but none of them were available in my Windows universal project. For example:
Graphics.MeasureString
TextRenderer.MeasureText
Edit:
This is not a web project.
I want to calculate the size it will take in the ui before it is in the ui.
I think you need to create a textblock in code and assign the desired text to it. Then you can get the actual height and width from it. See the below code
TextBlock txt=new TextBlock();
//set additional properties of textblock here . Such as font size,font family, width etc.
txt.Text = "your text here";
var height = txt.ActualHeight;
var width = txt.ActualWidth;
You can do further operations based on this height and width
I am not saying this is the optimized solution .But this will work for you
Try checking the values of the Width and Height properties of the control you use to display your text (eg. your TextBox), after setting your string as text/content, to decide whether to show another element.

Determine Control's 'AutoSize'-size at runtime

I want to layout controls during runtime (dynamically created). For the purpose of this question, let's restrict to a Button control. I want to set the control's properties (such as Text) and then determine the minimum size for the control for it to display properly; the size that setting AutoSize = true would give. In C# example code, with GetAutoSizeSize being this minimum size:
Button button = new Button();
this.Controls.Add(button);
button.Text = "Example";
button.Size = GetAutoSizeSize(button);
button.Location = /* Some calculation based on button.Size */
Possible solution: AutoSize
One can set button.AutoSize = true and button.AutoSizeMode = AutoSizeNode.GrowAndShrink. After that, the button.Size can be fetched, after which AutoSize can be turned off and the control size can be changed.
Potential issues:
It looks odd and I can't help but feel that this could easily break, but maybe I am wrong?
Possible solution: GetPreferredSize
button.GetPreferredSize can be used to get a size that the control wants to be.
Problems with this:
Its usage is internal and/or meant for flow layout.
GetPreferredSize takes a suggested size as a parameter, so one needs to guess at what would be appropriate.
The size returned is wrong, in that it returns the 'comfy' size of a control, which can be much larger than the minimum size that AutoSize gives.
EDIT: From the comments and some trial-and-error, I was able to conclude that the problems I originally listed with the AutoSize-method were due to needing both the control to be added to the control collection first and AutoSizeMode set to GrowAndShrink.
I would like to know if there is a function (and/or more 'robust' way) of determining the AutoSize-size: a function like GetPreferredSize that returns the size without actually having to toggle AutoSize.
This works when you are drawing on a control.
String sMyString = "this is my string";
Font fntFont = new Font("Arial", 8);
SizeF sfMySize = new SizeF(5,5);
sfMySize = System.Graphics.MeasureString(sMyString, fntFont, sfMySize);
This will give you the dimensions of the bounding box around the control text. You would have to work out the appropriate buffer around the text to set the button size.

how to get actual height of Grid Row before rendering

In my project there are many nested Grids. And mostly rows and columns width is defined as "*" in XAML.
I am trying to expand a particular row(lets say Row1) by seting other row's height to 0, and i am using the .ActualHeight property to get the width of Row1 then its not giving me actual height.
As per I know that is happening because height and width of Grid rows and columns are set on rendering time.
I searched on net and somebody suggested to use UpdateLayout() method ..but that is also not working for me.
I can not post code snippet because it is very long code.
my project in c#.net wpf.
You need to do a full layout update, that is you need to call Measure, Arrange and UpdateLayout:
//Make the framework (re)calculate the size of the element
_Element.Measure(new Size(Double.MaxValue, Double.MaxValue));
Size visualSize = _Element.DesiredSize;
_Element.Arrange(new Rect(new Point(0, 0), visualSize));
_Element.UpdateLayout();
_Element being a FrameworkElement (Grid is one).
Solution based on Baboon post worked for me. I needed to animate slide in of collapsed FrameworkElement, what is similar problem of not knowing ActualHeight value.
element.Visibility = Visibility.Visible;
element.InvalidateArrange();
element.UpdateLayout();
double elementHeight = element.DesiredSize.Height;
DoubleAnimation animation = new DoubleAnimation(0, elementHeight, TimeSpan.FromMilliseconds(animMilisec));
element.BeginAnimation(Rectangle.HeightProperty, animation);
Now before element is rendered I have access to it's final height;

Cannot modify expression because it is not a variable

I'm trying to get an UserControl (which has a grid on it) on a Windows Form to resize.
The below code is what I have in the Form. The behavior I'm getting is that the control is resized when I make it big. But it does not shrink. What am I doing wrong (or) What am I missing?
private void AdjustGrid()
{
ZoomControl.Location = new Point(5, 5);
ZoomControl.Size = new Size(this.Width - 15, this.Height - 75);
}
void zoomform_Resize(object sender, EventArgs e)
{
AdjustGrid();
}
Now the user control has the following code:
//Resize the grid that the UserControl has on it
private void NameValuePropertyBag_Resize(object sender, EventArgs e)
{
grdNameValueProperties.Location = new Point(4,4);
grdNameValueProperties.Size = new Size(this.Width - 8, this.Height - 8);
}
I tried
grdNameValueProperties.Size.Width = this.Width - 8;
grdNameValueProperties.Size.Height = this.Height -8;
It gives me "Cannot modify expression because it is not a variable" error... What am I missing?
Additional Info:
I'm using SetParent() Windows call to move/zoom an UserControl to another Form (ZoomForm).
Anchor doesn't seem to work for controls moved with SetParent()... More precisely, it may be working but I have repainting problems.
I got Anchor/Dock pair to working without repaint issues [I removed the resize event wireup and adjusted Dock to Fill]
The ZoomForm initally has no controls. The Usercontrol is added to the ParentForm dynamically.
Currently, I'm able to make the zoom form bigger with the above code but not smaller.
grdNameValueProperties.Size.Width = this.Width - 8;
grdNameValueProperties.Size.Height = this.Height - 8;
That code gives the error because Size is a value type, not a reference type. Reading this may help explain the difference between value types and reference types.
As recursive commented, you should just use the Anchor property.
The error occurse because the Size property exposes a struct and not a reference type. The Size property returns a copy of the size object of the control. Writing to the properties Width and Hight of this copy makes no sense because it is just a temporary copy and not backed by memory anywhere.
You can't directly change the Size.Width property on a UserControl, because the Size property is a value type, so changing its width would essentially be overwriting the entire Size property. Instead, controls in WinForms provide their own Width and Height properties, so this code should work:
grdNameValueProperties.Width = this.Width - 8;
grdNameValueProperties.Height = this.Height - 8;
Having said that, I agree with #recursive's comment that you should probably just use the UserControl's Anchor property to make it "automatically" resize.
Currently, I'm able to make the zoom form bigger with the above code but not smaller.
Some controls have a MinSize (or similar) property on them. Do you have any of those set such that you can't resize smaller?
For the first portion -
First off, I'd recommend using the Anchor property on UserControl instead of trying to size this yourself. It works very simply, and very reliably, for handling window resizing.
If you want to do this, you should probably look at chaining off this.ClientSize instead of this.Height and this.Width. You're probably setting your control too large, and that's unachoring the panel or other thing you're sitting on, which causes all sorts of issues.
The second part is due to the fact that gridNameValue Properties.Size.Width is a member of a struct.
When you call gridNameValueProperties.Size, you're returning a Size struct, then trying to set the Width on the returned struct (not the original). This is why you need to set the entire Size valuetype in one shot. Creating a new Size() and setting it to gridNameValueProperties.Size is the only way to make that work.

Categories

Resources