I am trying to draw a retangle inside a canvas width rounded corners, when I give this hardcoded the same size as the canvas it shows up perfect.
However when I use these lines to reference parent for width and height:
Height="{Binding ElementName=MyDesigner, Path=ActualHeight}"
Width="{Binding ElementName=MyDesigner, Path=ActualWidth}"
The right and bottom will exceed the canvas, I have attached a picture of the behaviour.
Anyone can give me a hint what is going wrong here?
Edit
The canvas xaml is:
<s:DesignerCanvas Focusable="true" x:Name="MyDesigner"
Background="{StaticResource WindowBackgroundBrush}"
FocusVisualStyle="{x:Null}"
ContextMenu="{StaticResource DesignerCanvasContextMenu}"
Width="300" Height="300">
<Rectangle
Height="{Binding ElementName=MyDesigner, Path=ActualHeight}"
Width="{Binding ElementName=MyDesigner, Path=ActualWidth}"
Fill="Transparent"
Stroke="Black" StrokeThickness="4"
RadiusX="20" RadiusY="20"
Canvas.Left="0"
Canvas.Top="0"/>
<Thumb Name="myThumb" Canvas.Bottom="0" Canvas.Right="0" Background="Blue"
Width="10" Height="10" DragDelta="onDragDelta"
DragStarted="onDragStarted" DragCompleted="onDragCompleted"/>
</s:DesignerCanvas>
The difference is when I change width and height of the retangle to 300 it fits perfectly.
DesignerCanvas, is a class that inherits canvas with few extra functions.
I assume the rectangle is initially drawn (bigger) and then resized to fit the Canvas (which is smaller or became smaller after the whole app was resized to fit the design). But Canvas will never do automatic resize (repaint) of it's children for you which means the changed shape won't show up or redraw itself. It will always show shapes exactly how the look like at the moment when added to the canvas's children.
If you want automatic resize you should choose a Grid or StackPanel as a host instead of the Canvas and set the rectangle's dimensions to Auto or it's Stretch property to 'Fill'. The grids will auto invalidate themselves and then redraw all contents.
Check the remarks of MSDN - Canvas Class. It's explained here...
Alternatively bind the Canvas.Children to a collection of your rectangles. You would then update rectangle dimensions to ActualHeight and ActualWidth whenever the Canvas.SizeChanged event is raised...or manually remove the old rectangle from the Canvas.Children collection and then add the resized one again.
Related
ViewBox seems to be the go to tool if you want your application to be re-sizable, however, I still cannot get my head around on how to properly use it.
Here's my current code (this approach was recommended by a colleague)
<Window x:Class="WpfApp3.MainWindow"
WindowState="Maximized"
Width="{DynamicResource {x:Static SystemParameters.MaximizedPrimaryScreenWidthKey}}"
Height="{DynamicResource {x:Static SystemParameters.MaximizedPrimaryScreenHeightKey}}">
<Viewbox Stretch="UniformToFill">
<Grid Background="Peru"
Height="1080"
Width="15000">
<Grid Background="Bisque"
HorizontalAlignment="Left"
Width="{DynamicResource {x:Static SystemParameters.MaximizedPrimaryScreenWidthKey}}" >
</Grid>
</Grid>
</Viewbox>
</Window>
The approach is the following:
Wrap everything in a ViewBox with Stretch property set to UniformToFill, such that the aspect ratio of inner-elements in preserved
For the outer most grid, set the Width to some arbitrary huge number and Height to some arbitrary small number
We now have a huge rectangle going off screen to the right, while the height is the height of the window
Create a second grid and horizontally align it the the left
Put all other elements in this grid
Problems
The width of the second grid is set to the width of the primary screen, but because of the ViewBox and its stretch property the width if cut off, so I cannot really use it, as all the elements will be slightly-aligned to the left of the screen
Current layout
Questions
Is this the recommended way of creating dynamic / re-sizable applications in WPF?
Is this the correct way of using the ViewBox control?
How can I fix my problem?
Are there other solutions to using the ViewBox control?
I had this issue when I was trying to make a telerik grid re-sizable. Using a viewbox is the recommended way of creating re-sizable applications in WPF. I've found that using a dock panel is better than margins because it holds the control in place, while the viewbox controls the sizing. You can also add a grid with rows / columns if you need multiple controls. I'm very new to development, so this may not be best practice, however it works for our applications.
<Viewbox Stretch="Fill"
Grid.Row="1"
Grid.Column="1">
<DockPanel Height="300">
<Grid>
*User controls*
</Grid>
</DockPanel>
</Viewbox>
I’m trying to use a Wingdings symbol as a graphic in a control and am trying to make it vertically centered within a textbox (UWP app.) I’m putting a visible boarder around it and the fact that the symbol is not vertically centered is noticeable and ruining what I’m going for. If it’s possible it saves me from having to do custom art and the since the Wingdings are resizable my graphic could be somewhat easily rescaled. That's why I don't want to manually adjust the height until it looks centered.
Most the Wingdings aren’t vertically centered but are sometimes used as graphics so I’m wondering if this is doable w/ reasonable effort. A slick xaml way to do this would be ideal but a font metric measuring and then textblock height adjusting tack would be good.
Here’s an example of the problem. The hard drive symbol is not vertically centered in the border.
<Border BorderBrush="Black" BorderThickness="10" Background="White" HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock Text=";" FontFamily="Wingdings" FontSize="230"/>
</Border>
EDIT - changed example to declutter and to use Wingdings hard drive symbol because the skull&bones is close enough to vertically centered to confuse the question. The drive symbol is very clearly not vertically centered. My goal to automatically vertically center it even as the font size changes. I can see how XAML may not be able to do this but I'm wondering if some font/text metrics querying exists that I could use to do it.
EDIT 2 - Adding a picture (from above XAML which has the same issues as all the suggested XAML(s):
I'm trying to get the center of the symbol to be at the center of the textblock
The skull & bones is not vertically centered in the border.
Actually by default the skull&bones text should be vertically center. The reason for why your code make it looks not vertically is that the font size is too larger to be inside the border, since Border's height is restricted to 200. So the exceed parts of TextBlock you will not seen which may looks like it is not vertically center.
How to vertically center a wingding character in textblock xaml / C# / UWP
There are several ways to do this, choose which way depend on your prefer.
Remove the height and width properties for the Border control you will see the text vertically center.
<Border BorderBrush="Black" BorderThickness="10" Background="White" HorizontalAlignment="Center">
<TextBlock x:Name="textBlock" Text="N" FontFamily="Wingdings" FontSize="230" />
</Border>
Add a ViewBox control outside the TextBlockcontrol. ViewBox can stretch and scale a single child to fill the available space. This will let your text looks always be center no matter how large is the font size. The text size will depend on the size of Border control. Code as follows:
<Border BorderBrush="Black" BorderThickness="10" Height="200" Width="175" Background="White" >
<Viewbox>
<TextBlock x:Name="textBlock" Text="N" FontFamily="Wingdings" FontSize="230" />
</Viewbox>
</Border>
Just use a TextBox control instead of the component of Border and TextBlock. This will reach the same effects that make the text always center and no matter what is the font size. Pay attention that don't set fixed height and width for the TextBox and also make the TextBox read only. Code as follows:
<TextBox
x:Name="textBox"
HorizontalAlignment="Center"
VerticalAlignment="Center"
BorderBrush="Black"
BorderThickness="10"
FontFamily="Wingdings"
FontSize="230"
IsReadOnly="True"
Text="N"
TextAlignment="Center" />
<Border CornerRadius="3" BorderBrush="#fff" BorderThickness="3px" Width="100" Height="100">
<Image Source="test.jpg" Width="100" Height="100"/>
</Border>
As shown in the code above, I've forced the Image to have 100 for both width and height as well as the border. My intention was so that the border can wrap the image without any unnecessary spaces. However please take a look at the result below:
There are still unnecessary spaces between the border and image? The problem can be solved by reducing the width and height of border but I just don't understand why. Below is my original image where width and height larger than 100:
You have set the BorderBrush property to White and the BorderThickness property to 3px on your Border. I can only imagine that that explains the white line around the edge of the Border. Just remove these properties to remove the white surrounding line.
UPDATE >>>
I would agree with #GazTheDestroyer. If your image is actually wider than 100px, then it will be automatically resized to fit into the 94px. If your image is wider than it is tall, then that would account for the gap at the top and bottom. try this:
<Image Source="test.jpg" Stretch="None" />
You can also experiment with the other possible values for the Stretch property.
A <Border> does not overlay an element, it contains an element. Therefore if your border is 100px with a 3px border, there are only 94px of space left inside.
Setting an explicit size of 100 on the image means that some of it will be chopped off since the border is not big enough to show all of it. Also I see you image is not square (120x103px), meaning it will be scaled with a strange aspect ratio too.
If you really want the border to overlay on top of the same exact square as the image, then put them both in a <Grid> or <Canvas> at the same position. eg
<Grid>
<Image Source="test.jpg" Width="100" Height="100"/>
<Border CornerRadius="3" BorderBrush="#fff" BorderThickness="3px" Width="100" Height="100" Background="Transparent">
</Grid>
I have a Windows Store app with a Hub page. On one HubSection i show a Image.
The Image should be Zoomable so i add a ScrollViewer and set ZoomMode to Enabled.
But now the Image is not scaled to the height of the Hub anymore. (It uses the size of the Bitmap)
If i remove the ScrollViewer the Image is scaled to the current Height and keeps the Height/Width ratio.
<ScrollViewer ZoomMode="Enabled" VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto">
<Image Source="{Binding Image1}" />
</ScrollViewer>
How can i get the ScrollViewer to Fill my Parent? (VerticalAlignment does not work)
Try putting VerticalScrollBarVisibility to Disabled, in that way the image height has to fit the height of the hub control.
I have an image control in a resizable window with its stretch property set to UniformToFill.
<Image Name="some_image" Stretch="UniformToFill" Margin="0,0,0,0" />
The clipping window is pegged to the top left of the image; resizing chops off the right and bottom of the image.
I want the image to be clipped equally on all sides. Am I being dense and overlooking an obvious solution?
How do I control how the image gets clipped?
(Unrelated: This is my first post to stackoverflow. I just wanted to start off saying, thanks, this site has been amazing resource for me)
The HorizontalAlignment and VerticalAlignment property determine this behavior with an image control.
<Image Name="some_image" Stretch="UniformToFill" Margin="0,0,0,0" HorizontalAlignment="Center" VerticalAlignment="Center" />
Guess i was being dense!