WPF Scaling Issue - wpf

I am perplexed with an issue that I am experiencing, using ScaleTransform. I have a Grid with a fixed width and height. The grid contains one child, a Rectangle. The Rectangle's Fill is a VisualBrush whose Visual binds to a canvas outside of the grid, whose dimensions are rather large. On the rectangle, I use a ScaleTransform, with ScaleX and ScaleY both being set to 0.18. Essentially, I am trying to scale the Rectangle's visual down to fit within my grid. What appears to be happening is that the Grid itself is being scaled down, resulting in a much smaller result than what I want. I have included the code below. Just as a point of reference, the height and width that the rectangle binds do are essentially 900 by 600, respectively. Any pointers as to what I might be doing wrong would be greatly appreciated.
<Grid Height="225" Width="200" Grid.Row="0" HorizontalAlignment="Left" VerticalAlignment="Top" x:Name="PART_Content">
<Rectangle Height="{Binding Path=ActualHeight}" Width="{Binding Path=ActualWidth}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Rectangle.Fill>
<VisualBrush Visual="{Binding}"/>
</Rectangle.Fill>
<Rectangle.RenderTransform>
<ScaleTransform ScaleX="0.183" ScaleY="0.183"/>
</Rectangle.RenderTransform>
</Rectangle>
</Grid>

Can you post the XAML for the Canvas element? I tried the following and I am getting the behavior you are going for (the rectangle is scaled and the grid is sized correctly)
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid ShowGridLines="True" Height="225" Width="200" Grid.Row="0" HorizontalAlignment="Left" VerticalAlignment="Top" x:Name="PART_Content">
<Rectangle Height="{Binding Path=ActualHeight}" Width="{Binding Path=ActualWidth}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Rectangle.Fill>
<VisualBrush Visual="{Binding ElementName=theCanvas}"/>
</Rectangle.Fill>
<Rectangle.RenderTransform>
<ScaleTransform ScaleX="0.183" ScaleY="0.183"/>
</Rectangle.RenderTransform>
</Rectangle>
</Grid>
<Canvas x:Name="theCanvas" Grid.Row="1">
<Rectangle Fill="Brown" Height="300" Width="300" />
</Canvas>
</Grid>

What is ActualWidth and ActualHeight? Unless I am mistaken the ActualHeight and ActualWidth properties as they normally mean in WPF are not DP's and you cannot bind to them. As has been pointed out below these are readonly dependency properties. Assuming this is in a CustomControl style Binding should be changed to TemplateBinding first.
I removed the bindings and essentially created a static version of your XAML which looks just fine. Since you have Part_Content defined for the grid, I am curious, is this xaml part of a custom control style? Is the code of the CustomControl manipulating the grid via PART_Content?
<Grid Height="225" Width="200" Grid.Row="0" HorizontalAlignment="Left" VerticalAlignment="Top" x:Name="PART_Content" Background="Red">
<Rectangle Height="225"
Width="200"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Fill="Blue">
<Rectangle.RenderTransform>
<ScaleTransform ScaleX="0.183" ScaleY="0.183"/>
</Rectangle.RenderTransform>
</Rectangle>
</Grid>

Related

WPF Border ZIndex not working as expected

I have the following problem: I overlay 2 controls over one another and want a single border to surround them both. I thought I could control the ZIndex of the border over each control and give them a low ZIndex: 2. Then give the controls a higher ZIndex (4 and 5). The following xaml as a UserControl is what I'm referring to:
<Canvas>
<Border BorderBrush="Black" BorderThickness="4" Canvas.ZIndex="2" Canvas.Left="50" Canvas.Top="30">
<Rectangle Width="200" Height="20" Fill="Aqua" Canvas.ZIndex="5"/>
</Border>
<Border BorderBrush="Black" BorderThickness="4" Canvas.ZIndex="2" Canvas.Left="150" Canvas.Top="00">
<Rectangle Width="50" Height="200" Fill="Yellow" Canvas.ZIndex="5"/>
</Border>
</Canvas>
The result looks like:
But I desire is the following image but with the border with red-X removed:
Can anyone recommend a way to do this ? The Border ZIndex method is not working.
Thanks!
ZIndex is not working cause Rectangles are not childs of Canvas. So you can fix it by placing them outside of borders and adjusting its Heights, Widths and Canvas.Left, Canvas.Top properties. So the example looks like this.
<Canvas>
<Border BorderBrush="Black" BorderThickness="4" Canvas.ZIndex="2"
Canvas.Left="46" Canvas.Top="26"
Width="208" Height="28">
</Border>
<Rectangle Width="200" Height="20" Fill="Aqua" Canvas.ZIndex="5"
Canvas.Left="50" Canvas.Top="30" />
<Border BorderBrush="Black" Height="208" Width="58" BorderThickness="4"
Canvas.ZIndex="2" Canvas.Left="146" Canvas.Top="00">
</Border>
<Rectangle Canvas.Left="150" Canvas.Top="4" Width="50" Height="200" Fill="Yellow"
Canvas.ZIndex="5"/>
</Canvas>

How to set an element's atribute from it's parent's attribute?

(I'm extremely new to xaml)
<Canvas Width="200" Height="100">
<Rectangle Width="" Height=""></Rectangle>
</Canvas>
Now, is it possible to set Rectangle's Width and Height the same as Canvas's using Xaml only?
or is necessary to use code?
You should make Data Binding. Looks like this:
<Canvas Name="myCanvas" Width="200" Height="100">
<Rectangle Width="{Binding ElementName=myCanvas, Path=Width}" Height="{Binding ElementName=myCanvas, Path=Height}"> </Rectangle>
</Canvas>

Visual brush weird behavior

I have a textbox and a rectangle. The rectangle updates itself when textbox content changes. I'm painting the rectangle fill with visual brush. The problem is that the visual brush don't match the textbox's actual look. What should I do. Here's my code:
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBox Name="txtBox"/>
<Rectangle Height="{Binding ElementName=txtBox, Path=ActualHeight}"
Width="{Binding ElementName=txtBox, Path=ActualWidth}">
<Rectangle.Fill>
<VisualBrush Visual="{Binding ElementName=txtBox}"/>
<Rectangle.Fill>
<Rectangle.LayoutTransform>
<ScaleTransform ScaleY="-0.75"/>
</Rectangle.LayoutTransform>
</Rectangle>
</StackPanel>
Here I wrote "Visual Brush",
then deleted few chars and look what I got:
Made a small change to your Xaml based on the information in your comment. The problem seems to be that the TextBlock doesn't have a Background so I guess that the VisualBrush just finds the visible part of the TextBlock for rendering and then stretches it to the full length of the TextBlock based on the Bindings.
The following Xaml works fine when the TextBlock has Background="Transparent" but reproduces your problem without it
Update: In the chat, the OP found that the Width Binding kept the TextBox from shrinking when deleting characters. So removing the Width binding fixes the centering issue as well.
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBox Name="txtBox"/>
<TextBlock Name="textBlock" Text="{Binding ElementName=txtBox, Path=Text}"
Background="Transparent"/>
<Rectangle Height="{Binding ElementName=textBlock, Path=ActualHeight}">
<Rectangle.Fill>
<VisualBrush Visual="{Binding ElementName=textBlock}"/>
</Rectangle.Fill>
<Rectangle.LayoutTransform>
<ScaleTransform ScaleY="5"/>
</Rectangle.LayoutTransform>
</Rectangle>
</StackPanel>

ScrollViewer enveloping a Grid not working properly

I am facing a strange problem with the ScrollViewer
I have a ScrollViewer with a Grid inside. The height of the Grid requires a vertical scrollbar. At runtime, the scrollbar is visible, but appears disabled and has no scroll indicator between the two arrows.
However, just above this scrollviewer is another set of controls enveloped by a scroll viewer, actually just the wayas the above, but here the scroll viewer is working just fine
here's the code
<Grid><Canvas Height="250" Width ="400" Margin="0,0,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Background="White" Name="ModeCanvas">
<Rectangle Width="{Binding ElementName=ModeCanvas,Path=ActualWidth}" Height="{Binding ElementName=ModeCanvas,Path=ActualHeight}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Stroke="Black" StrokeThickness="2"/>
<Grid Height="244" Width ="394" Margin="3,3,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Name="ModeParent">
<ScrollViewer VerticalScrollBarVisibility="Visible" >
<Grid VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Name="ModeGrid" >
</Grid>
</ScrollViewer>
</Grid>
</Grid>
</Canvas>
<Canvas Height="250" Width="400" Margin="0,255,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Background="White" Name="InputDataCanvas">
<Rectangle Width="{Binding ElementName=InputDataCanvas,Path=ActualWidth}" Height="{Binding ElementName=InputDataCanvas,Path=ActualHeight}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Stroke="Black" StrokeThickness="2"/>
<Grid Margin="5,5,5,5" Width="390" Height="240" Name="InputDataParent">
<ScrollViewer VerticalScrollBarVisibility="Visible" >
<Grid VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Name="InputDataGrid" >
</Grid>
</ScrollViewer>
</Grid>
</Canvas>
<Canvas Margin="0,510,0,0" Height="250" Width ="400" VerticalAlignment="Top" HorizontalAlignment="Left" Background="White" Name="OutputDataCanvas">
<Rectangle Width="{Binding ElementName=OutputDataCanvas,Path=ActualWidth}" Height="{Binding ElementName=OutputDataCanvas,Path=ActualHeight}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Stroke="Black" StrokeThickness="2" />
<Grid Margin="5,5,5,5" Width="390" Height="240" Name="OutputDataParent">
<ScrollViewer VerticalScrollBarVisibility="Visible">
<Grid VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Name="OutputDataGrid">
</Grid>
</ScrollViewer>
</Grid>
</Canvas>
In this code - the first 2 Canvas render the scrollbar just fine, but for some reason the third one is creating a problem
Any Ideas ??
EDIT
Finally got the mistake in the code. The probelm was in the code behind.
The basic probelm was that when we resize the window at that time some code behind code was changing the heights of the first 2 Grids but not of the third Grid. Initially the data that was inserted in each Grid(dynamically) was such that, the first 2 Grids used to overflow but not the 3rd one, . So, now when i resized the window the third Grid still did not have a scroll viewer even though now the data was overflowing the space,giving an impression that the scroll viewer was not activating.
However, i missed the simple fact, that the height of the 3rd grid was not changing, whereas the first 2 Grids height was changing, thus the scroll viewer for the first 2 grids was properly working but not the 3rd.
The Grid inside the ScrollViewer is empty. What the scrollviewer is expect to scroll?

WPF : Rounded-Corners Images

<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Background="Black">
<!-- Rounded yellow border -->
<Border BorderThickness="3" BorderBrush="Yellow" CornerRadius="10" Padding="2"
HorizontalAlignment="Center" VerticalAlignment="Center">
<Grid>
<!-- Rounded mask (stretches to fill Grid) -->
<Border Name="mask" Background="White" CornerRadius="7"/>
<!-- Main content container -->
<StackPanel>
<!-- Use a VisualBrush of 'mask' as the opacity mask -->
<StackPanel.OpacityMask>
<VisualBrush Visual="{Binding ElementName=mask}"/>
</StackPanel.OpacityMask>
<!-- Any content -->
<Image Source="http://chriscavanagh.files.wordpress.com/2006/12/chriss-blog-banner.jpg"/>
<Rectangle Height="50" Fill="Red"/>
<Rectangle Height="50" Fill="White"/>
<Rectangle Height="50" Fill="Blue"/>
</StackPanel>
</Grid>
</Border>
</Page>
This XAML is from WPF – Easy rounded corners for anything but it doesn't work form me =(
<Border Canvas.Left="55"
Canvas.Top="30"
Width="100"
Height="Auto"
Margin="12,12,8,0"
VerticalAlignment="Top"
BorderBrush="#FF3B5998"
BorderThickness=".5"
CornerRadius="18">
<Border.Effect>
<DropShadowEffect BlurRadius="5"
Opacity=".5"
ShadowDepth="3" />
</Border.Effect>
<Border Name="ReceiverColor"
BorderBrush="#FF96B2E4"
BorderThickness="6"
CornerRadius="15">
<Border Name="Mask"
BorderBrush="#FF3B5998"
BorderThickness=".5"
CornerRadius="13">
<StackPanel>
<StackPanel.OpacityMask>
<VisualBrush Visual="{Binding ElementName=Mask}" />
</StackPanel.OpacityMask>
<Image Name="Receiver" />
</StackPanel>
</Border>
</Border>
</Border>
--- EDIT ---
I make borders sizes to auto and change source of image to an image from a link
when window loaded border size becomes as image size but image not shown !!!
You can define a <Border/> element and set its <Border.Background/>
property to an <ImageBrush/> , set the Borders CornerRadius property and you
are all set!
<Border CornerRadius="8,0,8,0">
<Border.Background>
<ImageBrush Stretch="Fill" ImageSource="ImageSource"/>
</Border.Background>
</Border>
You forgot the Grid that makes the mask and the image siblings and nested the image in the mask. and you forgot to set the background of the mask.
This works:
<Grid>
<Border Canvas.Left="55"
Canvas.Top="30"
Width="100"
Height="Auto"
Margin="12,12,8,0"
VerticalAlignment="Top"
BorderBrush="#FF3B5998"
BorderThickness=".5"
CornerRadius="18">
<Border.Effect>
<DropShadowEffect BlurRadius="5"
Opacity=".5"
ShadowDepth="3" />
</Border.Effect>
<Border Name="ReceiverColor"
BorderBrush="#FF96B2E4"
BorderThickness="6"
CornerRadius="15">
<Grid>
<Border Name="Mask"
Background="White"
BorderBrush="#FF3B5998"
BorderThickness=".5"
CornerRadius="13">
</Border>
<StackPanel>
<Image Name="Receiver"
Source="/Images/test.jpg" />
<StackPanel.OpacityMask>
<VisualBrush Visual="{Binding ElementName=Mask}" />
</StackPanel.OpacityMask>
</StackPanel>
</Grid>
</Border>
</Border>
</Grid>
in wpf this one works for me
<Ellipse Width="50" Height="50">
<Ellipse.Fill>
<ImageBrush ImageSource="http://chriscavanagh.files.wordpress.com/2006/12/chriss-blog-banner.jpg" />
</Ellipse.Fill>
</Ellipse>
None of the above answers worked for me completely. I was trying to implement rounded corners on image which could be resized and has properties Stretch="UniformToFill" VerticalAlignment="Center" and HorizontalAlignment="Center".
The center alignments keeps the middle part cropped as opposed to bottom and right side being cropped, when image is resized. Solutions with image brush were working but I was facing problem in keeping the content at center cropped.
The marked answer has a problem with transparent non rectangular images as the "mask" border will end up showing as white background. Following was the imlementation which worked for me:
<Grid>
<WrapPanel Name ="container">
<Image Source="sample_image.png" VerticalAlignment="Center" HorizontalAlignment="Center" Stretch="UniformToFill"/>
<WrapPanel.OpacityMask>
<VisualBrush >
<VisualBrush.Visual>
<Border Height="{Binding ElementName=container, Path=ActualHeight}"
Width="{Binding ElementName=container, Path=ActualWidth}"
Background="White" CornerRadius="15" />
</VisualBrush.Visual>
</VisualBrush>
</WrapPanel.OpacityMask>
</WrapPanel>
</Grid>
You can use an ellipse like how Usman Ali has said (I thought this myself and I didn't take it from him)
It's very simple, make an ellipse with the properties you want, then set the fill to an imagebrush with your desired image like this in XAML:
<Ellipse Height="Auto" Width="100">
<Ellipse.Fill>
<ImageBrush ImageSource="YOUR IMAGE SOURCE/LINK HERE"/>
</Ellipse.Fill>
</Ellipse>
In C#, if in any case you want to do in C#:
Ellipse YourEllipseName = new Ellipse
{
Height = 50,
Width = 50,
StrokeThickness = 0,
Fill = new ImageBrush
{
Stretch = Stretch.Uniform,
ImageSource = new BitmapImage(new Uri("YOUR IMAGE SOURCE HERE"))
}
};
<Grid Background="Black">
<Rectangle RadiusX="20" RadiusY="20"
Width="130"
Height="130">
<Rectangle.Fill>
<ImageBrush x:Name="myImage" ImageSource="C:\Path\Desktop\visual-studio-2010-logo.png"/>
</Rectangle.Fill>
</Rectangle>
</Grid>

Resources