How to tell Size of a Grid Cell? - silverlight

I have a custom control that I've placed inside a cell of a grid. I have some internal calculations I need to run based on the height and width of the custom control. However, I want it to resize based on the size of the cell.
So, my main question is... how to I programatically determine the height and width of a given cell?

It may be easier to figure out the Height and Width of your Custom Control rather than the cell of a DataGrid.
Your control should have access (through FrameWork Element) to the properties ActualHeight and ActualWidth. These properties will update when the size changes.
Also, the SizedChanged event will be fired on your control every time the Height and Width change.
I highly recommend placing this height and width logic inside of your control. You do not want to be limited to only placing your custom control inside of DataGrids.
private void UserControl_SizeChanged(object sender, System.Windows.SizeChangedEventArgs e)
{
HeightBox.Text = this.ActualHeight.ToString();
}

You can get size of grid cell through RowDefinitions and ColumnDefinitions:
MyGrid.RowDefinitions[1].ActualHeight
MyGrid.ColumnDefinitions[1].ActualWidth
but it should be pretty rare situation then you have to resort to this kind of approach

Related

How check if there are more rows to display than datagrid height allows

How check if there are more rows (rows height) to display than datagrid height allows. Default behaviour is when rows are more than datagrid height scrollbar is displayed. Other behaviour can be set SizeToContent="Height".
I want' to override method or bind to event in which I can decide whether scrollbar is displayed or increase window height. This is best option to pick.
Maybe someone have other solutions how can I handle with this problem.
Let me insist on using standard WPF features : If you want to have this behaviour :
a) DataGrid takes the least possible height.
b) DataGrid can take up to a given height.
c) When content does not fit that max length, scrollViewer should activate.
Then setting DataGrid's MaxHeight (and only that) is enough, that's exactly the behaviour you will get.
If it is not the behaviour you see, check the Panel in which your DataGrid is inserted, and make sure the issue comes from here.
If you are using a StackPanel, switch right-now to a Grid : StackPanel are champions when it comes to induce strange measure/arrange bugs.

WPF ScrollViewer set ScrollableHeight

I have a user control which paints content in OnRender. The Height of that control grows by and by.
I added this control to a ScrollViewer. The control does only repaint the currently visible area (viewport) (+/- a view lines for smoother scrolling).
Everything works fine so far...
But since the control usualy grows up to a few hundred thousands of pixels I want to keep the Height of my control as small as possible and provide a different Height value to bind to the ScrollableHeight of the ScrollViewer (same goes for VerticalOffset). But there is no setter for ScrollableHeight. It binds automatically to the Height of my Control. Neither can I override Height.
How can I customize my ScrollViewer (or VerticalScrollbar) to keep the real Height of my control small?
I did something like this in the past. What you need to do is to write your own layout Panel and implement the IScrollInfo in it. The interface looks big, but most of it is just calling one of the main set methods. The layouter needs to set some of the IScrollInfo properties, like ExtentHeight, Offset etc. and these are your way to customize how the ScrollViewer will calculate the scroll position and the scrollable area for your "virtual" canvas size. For implementing the IScrollInfo i used this tutorial as a guidance.

WPF - getting the REAL width of a control

I want to set the MinWidth of a Grid ColumnDefinitions to the ActualWidth of a DataGrid inside it.
The main problem is the DataGrid has a (built-in) vertical scroller since its contents are many. So, the actual width is the size of its columns and some more, but not including the scroller.
What happens is that when I set the MinWidth, I get the rightmost column hidden behind the scroller.
I appreciate solving this both in the code and the XAML (just in order to learn).
Try putting the DataGrid into a Canvas and bind to the ActualWidth property of that instead.

Setting control height explicitly

I have a XamDataGrid in one of my user controls, inside of a stackpanel. I want the grid to maintain the same height regardless of how many rows are present in the grid. To do that, I set the grid's Height property to an explicit value.
Is that how things are done in WPF? Every time I do explicit sizing I feel like I am doing WinForms and not using WPF properly. Is setting the Height directly the only/correct solution?
There's nothing wrong with setting an explicit Height in situations where you want an element to always stay the same height. Where it's less appropriate is in situations where sizing is better handled by the parent layout Panel or the element's child content which can use the available space dynamically.
WPF uses a relative measurement system which at first glance is not intuitive. I have never found an example when I was forced to use explicit sizes ( once when I paint something on Canvas). I use styles in 90% cases where I define Padding, Margin, Aligment etc. Sometimes I use MinHeight and MinWidth for simple things.
About that Grid you can put it in the ScrollViewer or ViewBox to have dynamic sizing, yet If it won't be trouble set the explicit Height.

Panel with percentage coordinates

I would like use a panel whose children have coordinates specified as percentage of total panel's width/height. Moreover, I should be able to animate the coordinate property, for example to make a button move from 10% to 50% panel's width.
I've made 2 attempts:
Use a Grid and specify size as stars - this was not enough, because AFAIK by default WPF cannot animate distance properties specified by stars. I've found somewhere a custom class that enabled me to do so, it even worked, hovewer I consider that solution overly complicated an I am looking for something simpler.
Use a Canvas with fixed width and height and put it inside a Viewbox - this is a simple solution, but when resizing the Viewbox the whole content of Canvas is resized too. I want the content to have fixed size.
Is there a simple solution or should I implement my own panel (or maybe extend one of the existing ones, i.e. Canvas)?
Cheers!
I would:
subclass Canvas, perhaps calling it RelativeCanvas or RatioCanvas
add two attached properties: XRatio and YRatio
override ArrangeOverride and loop over all children. For each child, use their XRatio and YRatio along with the ActualWidth and ActualHeight of the RelativeCanvas to calculate and apply values for their Canvas.Left and Canvas.Top attached properties
You would use it as follows:
<local:RelativeCanvas>
<!-- the top-left of this button will be center of panel -->
<Button local:RelativeCanvas.XRatio="50" local:RelativeCanvas.YRatio="50"/>
</local:RelativeCanvas>
One thing you might like to add after you get that working is control over alignment. For example, I might to align the center of a control to the specified ratio, not its top-left corner.
There's one here: WPF Proportional Panel

Resources