I have a Viewbox with Stretch=Uniform in order to not distort the content.
However, when the frame window is wider or taller than the content, the Viewbox content is always centered.
I cannot seem to find any content alignment options on the Viewbox.
Is there a way to do this?
Try VerticalAlignment="Top" and HorizontalAlignment="Left" on your viewbox. It will cause it to be anchored to the top and left side.
<Grid>
<Viewbox VerticalAlignment="Top" HorizontalAlignment="Left">
...
</Viewbox>
</Grid>
If you want it to completely fill (but keep it uniform) you can use Stretch="UniformToFill"
According to MSDN the Viewbox is used to stretch the child elements. Since the child elements would be stretched, you would have to set the content alignment of the children.
You may want to look at this for more information on the Viewbox: How do I keep aspect ratio on scalable, scrollable content in WPF?
Related
I have a 50x50 draggable grid inside another grid that I am able to move around with the cursor. (I forgot that I am using the DraggableExtender class
The problem is that I want the moveable grid to be relatively positioned inside it's container grid no matter how the container grid is resized. My solution right now is to dynamically change the HorizontalAlignment and VerticalAlignment of the moveable grid whenever it is moved, but this is hacky and doesn't work well.
Relative positioning in a grid is one of the easiest things to do in XAML, but not when you have draggable elements ;(
Any ideas?
EDIT for code and images:
My XAML:
<Grid Margin="10" ClipToBounds="True" Background="#FFB4B4B4">
<Grid Name="testGrid" MouseLeftButtonDown="testGrid_MouseLeftButtonDown" MouseLeftButtonUp="testGrid_MouseLeftButtonUp" RenderTransformOrigin="0.5,0.5" Height="100" Margin="50,0,0,0" Width="100" Background="#FFE6E6E6" local:DraggableExtenderGrid.CanDrag="true" HorizontalAlignment="Center"/>
</Grid>
and I use a DraggableExtender class (shown here) which I have edited to apply to a Grid instead of a Canvas (I was hoping for better results from a grid.. but both containers produce the same result, even with the original class on a canvas).
This is a picture of my 2 grids. I can move the smaller grid around inside it's parent grid, but I would like for it to maintain relative positioning once the window is resized. This is what it currently looks like when I resize the window. In this particular example, the grid would ideally remain slightly off-center horizontally and vertically in both pictures.
May be you should try placing the Grid inside a Canvas instead..
Take a look here
In the image here, each block with a number in it represents a laser. These blocks are laid out on a canvas inside a DockPanel. Also inside the DockPanel docked to the top is the red TextBlock that you can see is hiding behind the laser map canvas. Why is this happening? The TextBlock is docked to the top of the DockPanel and canvas has no dock setting, therefore it should fill the rest of space. Also of note: I had to put the DockPanel inside a ViewBox in order for the whole center screen space to scale properly on window resizes. Then I had to put that ViewBox inside a ScrollViewer to allow scroll bars to appear when needed.
Here is the XAML Code for the center screen (Note: Child of the Window is a DockPanel. Menu is docked to the top, left-hand button panel is docked to the left, right-hand button panel is docked to the right, the status bar is docked to the bottom and everything you see in the center screen is defined by the following XAML code)
<ScrollViewer
Name="centerScreenScrollViewer"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="{Binding IsScrollbarsVisible, Converter={StaticResource BoolToScrollbarVisConverter}, FallbackValue=Hidden}">
<Viewbox>
<DockPanel
LastChildFill="True">
<TextBlock
DockPanel.Dock="Top"
Name="tbkFullVisual"
Style="{StaticResource tbkStyleBlue}"
Foreground="Red"
IsEnabled="{Binding FullVisual}"
HorizontalAlignment="Center"
VerticalAlignment="Top"
FontSize="24">
*** This Print Requires Full Visual Inspection! ***
</TextBlock>
<Canvas x:Name="mapCanvas">
<ContentPresenter Content="{Binding MapCanvas}"/>
</Canvas>
</DockPanel>
</Viewbox>
</ScrollViewer>
Any help in solving this issue will be greatly appreciated.
Regards,
Kyle
This has to do with the way that a ViewBox works, in particular with the Canvas element. The ViewBox is used to resize child elements, as I'm sure you're aware. There are 2 issues with the Canvas element:
The default Height and Width are 0, which means that the TextBlock will get all the space.
The Canvas element lets you draw outside of its own boundaries, so even if your canvas is tiny or not even visible, you would be allowed to render your grid of numbers.
The quickest solution is to set VerticalAlignment on the ViewBox:
<Viewbox VerticalAlignment="Top">
...
</Viewbox>
You could set a Height on the Canvas, but I think this is less ideal because you don't want to change this dynamically with window resize.
Imagine this. I've got a Border which contains some custom wpf control, lets call it MyControl. This Border stretches itself when window is resized (to fill available space). MyControl size is fixed. Now, I want my control to have HorizontalAlignment="Center" when it fits the available space, and HorizontalAlignment="Left" when it doesn't. I'm having trouble figuring out how to implement such behaviour though.
I guess, i can subscribe to Border's SizeChanged event and change alignment in code-behind depending on ActualWidths of Border and MyControl, but isn't there an easier way? Can this be achieved by databinding or by attached behaviour?
It will automatically behave like that if you set the control's Width and Height to fixed values and HorizontalAlignment and VerticalAlignment to Stretch instead of Center:
<Border BorderBrush="Red" BorderThickness="5">
<my:MyControl Width="200" Height="150"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
</Border>
i am currently working on a sample for a lib that i wrote,designed to execute WebRequests such as POST and GET safely. At the moment i am trying to figure out a way to show the response of the request (Usually, HTML text) in my window.
It does not need to be fancy,but i thought about a Textblock that can scroll,but i can't seem to make mine works.
Here is what i am trying:
<ScrollViewer Height="439" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="546,19,0,0" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" Name="Scroller">
<TextBlock HorizontalAlignment="Stretch" VerticalAlignment="Stretch" MinWidth="100" Width="433"
TextWrapping="Wrap" Name="block" Height="440" />
</ScrollViewer>
What happens is that my content scrolls,but it does not appears fully in the window,it gets cut for some reason and i can't see all of the return.
Any other advice of how to do it ?
Thanks !
The Height of the TextBlock is fixed at 440. You should remove that.
You have way too many hard-coded sizes, remove the Width and Height of the TextBlock. If you want it to scroll you need to allow it to take all the space it wants.
Your scrollviewer is handling the scrolling and that is what requires the fixed height, as #Erno said the TextBlock within is also fixed height and it shouldn't be.
The content within the ScrollViewer should be as high as it needs to be, the ScrollViewer will handle the scrolling of that based on it's own height.
I have simple canvas with items and i need to add for scroll view as parent for my canvas.
But i fased with problem that after set
canvas.RenderTransform=new ScaleTransform(){...}
Scroolbars not appears or working not correctly.
Will be glad for any information.
The render transform occurs much later in the UI rendering process. It ultimately performs a matrix transform on controls rendering. The scroll viewer will be completely unware of this transform, its scrollbars will be based on the un-transformed size of the original Canvas.
The silverlight toolkit contains a LayoutTransformer control. This control applies a transform to its content as part of the layout process and reports the post-transform size as its desired size.
Consider this:-
<ScrollViewer Width="200" Height="200" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<toolkit:LayoutTransformer>
<toolkit:LayoutTransformer.LayoutTransform>
<ScaleTransform ScaleX="2" ScaleY="2" />
</toolkit:LayoutTransformer.LayoutTransform>
<Canvas Width="150" Height="150" Background="Aquamarine">
<Rectangle Fill="Blue" Canvas.Top="10" Canvas.Left="10" Width="30" Height="30" />
</Canvas>
</toolkit:LayoutTransformer>
</ScrollViewer>
Whilst the Canvas has a size (150) smaller than the containing scroll viewer (200), it is scaled so that it would be larger (300). The LayoutTransformer reports its desired size as 300, the post-transform size of the canvas. Hence the ScrollViewer displays scroll bars to accomodate it. Without the benefit of the LayoutTransformer the ScrollViewer would only see the Canvas as having a size 150 despite any applied RenderTransform.