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;
Related
I'm trying to get the size (width/height) of an Image control after I applied a Transform to it (either Render- or Layouttransform, doesn't matter in this case).
My Image control is embedded in a ScrollViewer. I'm using the Layout/Rendertransform to zoom the image which does work, but the ActualWidth/ActualHeight or RenderSize properties don't show me the new height/width. I tried calling InvalidateMeasure()and UpdateLayout() on the Image control without success.
This is my current code to zoom the image to the height:
double imageHeight = imageBox.ActualHeight;
double containerHeight = (imageBox.Parent as ScrollViewer).ActualHeight;
double facHeight = containerHeight / imageHeight;
var scaleTransform = imageBox.LayoutTransform.Value; //imageBox.RenderTransform.Value;
scaleTransform.ScalePrepend(facHeight, facHeight);
MatrixTransform newTransform = new MatrixTransform(scaleTransform);
imageBox.LayoutTransform = newTransform;
On first execution of that method the image will be (more or less) correctly zoomed. In this case, I want the image vertically fully shown, regardless of it's width, so that I only have a horizontal scrollbar (or no scrollbar at all if imageHeight > imageWidth).
On second execution, it'll zoom in again because imageBox.ActualHeight didn't change.
I tried various combinations of InvalidateMeasure and UpdateLayout but that didn't help.
For the transformed size after LayoutTransform (but not RenderTransform) was applied, check the Image control's DesiredSize property:
double imageHeight = imageBox.DesiredSize.Height;
hello I have the following problem: I want to draw a rectangle on the canvas with methods Canvas.SetLeft() and Canvas.SetTop().
I use the method UserControl_Loaded() and everything works.
the problem is that having ActualWidth when resizing the window and therefore the grid, the value does not change and I left with the values no longer accurate.
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
Rectangle rett = new Rectangle();
rett.Height = grid1.ActualHeight-10;
rett.Width = grid1.ActualWidth -10;
rett.Fill = new SolidColorBrush(Colors.LightBlue);
canv.Children.Add(rett);
Canvas.SetLeft(rett, 10);
Canvas.SetTop(rett, 10);
}
this is the xaml:
<Grid x:Name="grid1">
<Canvas x:Name="canv" Height="auto" Width="auto"></Canvas>
</Grid>
in the first picture it is fine when not resize the window.
the second when I resize the grid remains the previous width.
I want the width of the rectangle was updated when changing the width of the grid.
Thank you.
Without a good, minimal, complete code example that clearly illustrates your question, along with a detailed explanation of what you're actually trying to accomplish (especially in a broader sense), it is impossible to know for sure what the best answer in your case would be.
Taking your question literally, it seems one possible approach would be to bind the Rectangle dimensions to the Grid's dimensions, so that they are updated as the Grid changes size. You can use IValueConverter to subtract the appropriate amount from the actual dimensions.
But that's a fairly complicated solution for what would otherwise be a reasonably simple problem, and especially so given that you seem to be doing this in code-behind for some reason (not ideal in the first place, and setting up bindings in code-behind is particularly tedious).
Idiomatically, what you should probably be doing is not putting the Rectangle in the Canvas at all, but rather making it a child of the Grid directly. Then you can set its alignments to Stretch so that it will fill the grid cell it's in. Finally, you can set its margins so that you have the 10 pixel gap on the top and left, and no gap on the right and bottom.
For example:
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
Rectangle rett = new Rectangle();
rett.Fill = new SolidColorBrush(Colors.LightBlue);
// NOTE: technically don't need to set these, as Stretch is the default value!
rett.HorizontalAlignment = HorizontalAlignment.Stretch;
rett.VerticalAlignment = VerticalAlignment .Stretch;
// 10 pixels of margin on top and left, none on right and bottom
rett.Margin = new Thickness(10, 10, 0, 0);
grid1.Children.Add(rett);
}
Doing it as above allows the XAML layout engine to automatically handle the resizing behavior you are looking for.
All that said, I would definitely encourage you to implement this in XAML instead of code-behind. There are a lot of things code-behind is good at, but frankly XAML is much better at any of the things directly related to the configuration of your GUI object graph.
I currently have a chart created in my project as follows:
Chart c = new Chart{
Width = 1000,
Height = 1000,
};
This will create a chart that is 1000 pixels wide and 1000 pixels high. My question is, is there a way to have these values set dynamically so that it could take up a particular portion of the screen? For example if I wanted it to take up 80% of the screen's width and 50% of the height, is there a way to tell it to do that instead of giving static pixel values? If that cannot be done, is there a way to simply have it stretch to the size of its container in the HTML?
So pretty much right after I posted this, I figured out a solution. The chart is displayed in the View via <img> tag, so I can set the style width and height within that tag to change the size of the displayed chart
I'm creating a custom canvas which has dynamically added shapes (lines) which are added as children. Unfortunately, after adding the children, the canvas has a width of 0, which is not expected.
Ideally, the canvas should update its width by using its children's dimensions.
How can I modify my canvas to account for the dimensions of its children, and then update its width?
As I said, I changed the shapes on the canvas dynamically. I do this every time one of its dependency properties is changed using a callback function.
Generally, this is what that callback function looks like:
This is not my algorithm, but it should demonstrate the point.
public void UpdateLines()
{
for(int i = 0; i < NUM_BARS; i++)
{
Line bar = new Line();
bar.Stroke = Brushes.Black;
bar.StrokeThickness = 4;
bar.X1 = 0;
bar.X2 = ActualWidth;
bar.Y1 = i * (bar.StrokeThickness + 2);
bar.Y1 = bar.Y2;
this.Children.Add(bar);
}
//[Inserted here]
}
The next thing I noticed is that I could add a line with a large length, and that line would appear, but the canvas width would still remain 0.
At the "Inserted Here" mark, I put this line of code to test:
Children.Add(new Line() { Stroke=Brushes.Black,
StrokeThickness = 4, X1 = 0, X2 = 200, Y1 = 10, Y2 = 10 });
So, why the canvas width is not updating properly? I need to use it for calculating the size of my lines.
Your help is greatly appreciated. Thanks.
Please refer to the Panels Overview page on MSDN for further help with WPF Panels, but in short, the Canvas Panel does not resize itself when child items are added (or at any time). From the linked page:
Canvas is not affected by the size of its children. As a result, it is possible for a child element to overdraw other elements outside the bounding rectangle of the parent Canvas.
Therefore, you will either need to manually update the size of the Canvas, or use a different type of layout Panel that does resize itself when child items are added, although the Canvas is the only Panel that enables users to place child controls at absolute positions within it.
Again, from the linked page:
Canvas provides the most flexible layout support of any Panel. Height and Width properties are used to define the area of the canvas, and elements inside are assigned absolute coordinates relative to the area of the parent Canvas. Four attached properties, Canvas.Left, Canvas.Top, Canvas.Right and Canvas.Bottom, allow fine control of object placement within a Canvas, allowing the developer to position and arrange elements precisely on the screen.
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