I have the following controls in xaml:
<Canvas Height="500" Width="500" Name="canPreview" VerticalAlignment="top" Grid.Row="1" Grid.RowSpan="3" MouseLeftButtonDown="canPreview_MouseLeftButtonDown"
MouseLeftButtonUp="canPreview_MouseLeftButtonUp" MouseLeave="canPreview_MouseLeave" MouseMove="canPreview_MouseMove"
Height="{Binding Path=ActualHeight, ElementName=imgPreview}" Width="{Binding Path=ActualWidth, ElementName=imgPreview}">
<Rectangle Name="recSelection" StrokeThickness="2" Stroke="Black" Fill="Transparent" Opacity=".5" Height="100" Width="100" />
</Canvas>
And for some reason the Canvas events only fire when the mouse pointer is above the rectangle. Any idea what is going on?
Set the background color of the Canvas; you can't click something that isn't drawn.
You can use the Transparent brush if you do not want to see the canvas, it will be clickable.
Related
Attempting to centre my label in my User Control to my 'signal' I have drawn within my canvas.
This is what my signals currently look like, with their names below the signal. As you can see, due to the variation in name length, some are off centred.
My user control XAML code:
<UserControl x:Name="LeftUserControl"
d:DesignHeight="50" d:DesignWidth="50" RenderTransformOrigin="0.84,0.5">
<Viewbox Stretch="Uniform" Width="10" Height="10">
<Canvas Height="150" Width="150">
<Label Content="{Binding SignalName, ElementName=LeftUserControl}" Foreground="Black" Canvas.Top="108" FontSize="15" Canvas.Left="85"></Label>
<Line X1="130" X2="130" Y1="105" Y2="84" Stroke="Black" StrokeThickness="5" StrokeStartLineCap="Round" ></Line>
<Line X1="130" X2="100" Y1="105" Y2="105" Stroke="Black" StrokeThickness="5"></Line>
<Ellipse Fill="Red" Width="25" Height="25" Canvas.Left="85" Canvas.Top="92"/>
</Canvas>
</Viewbox>
</UserControl>
My main window where I'm using my user control:
<DataTemplate DataType="{x:Type viewModel:SignalLeftViewModel}">
<Canvas>
<userControls:SignalLeftControl SignalName="{Binding Name}" Canvas.Top="{Binding SignalCoords.Y, Converter={StaticResource ScaleYCoordConverter},ConverterParameter=leftSignal}" Canvas.Left="{Binding SignalCoords.X, Converter={StaticResource ScaleXCoordConverter}, ConverterParameter=leftSignal}">
<userControls:SignalLeftControl.RenderTransform>
<RotateTransform Angle="{Binding Angle}"/>
</userControls:SignalLeftControl.RenderTransform>
</userControls:SignalLeftControl>
</Canvas>
</DataTemplate>
I'm wondering what the easiest way is to centre my label within my user control, so that all the names are aligned properly. Thanks in advance.
When I place the following code in a Window or UserControl, the image is displayed with its native width and height. Is there a way to automatically scale outer canvas to proportions of the containing window while retaining the proper aspect ratio for the window?
<Canvas Background="AliceBlue">
<Canvas.LayoutTransform>
<ScaleTransform ScaleX="1" ScaleY="1"/>
</Canvas.LayoutTransform>
<Image Source="ImageName.jpg" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Canvas Canvas.Top="20" Canvas.Left="20" Width="20" Height="20" Background="Salmon"/>
</Canvas>
A Canvas never resizes its child elements. Put the Image control in a Grid instead, then probably put the whole thing in a Viewbox:
<Viewbox>
<Grid>
<Image Stretch="None" Source="ImageName.jpg" .../>
<Canvas Margin="20,20,0,0" Width="20" Height="20" Background="Salmon"/>
</Grid>
</Viewbox>
Wrap your Canvas in a ViewBox.
When i draw items in canvas, the position is take from top of the item inside canvas:
<Canvas Name="cnvMain"
Width="80"
Height="80">
<Ellipse Canvas.Top="20"
Canvas.Left="40"
Width="40"
Height="40"
Fill="Gray" />
</Canvas>
Now what i would need is to take the measurement from the bottom of the element, like this:
In the end i would like to be able to set the distance from the bottom of the Ellipse to the top of the Canvas.
NB: Ellipse can sometimes not be a circle and flipping it upside down is not an option. Also i dont know the height before runtime so setting negative margin in xaml will not work also.
(Picture and example xaml taken from: http://weblogs.asp.net/psheriff/centering-text-within-a-wpf-shape-using-a-canvas)
If you want to specify the distance of the bottom of the Ellipse to the bottom of the Canvas, you could replace Canvas.Top by Canvas.Bottom:
<Ellipse Canvas.Bottom="20" Canvas.Left="40" Width="40" Height="40" Fill="Gray"/>
For the distance from the bottom of the Ellipse to the top of the Canvas, you may specify a negative Margin:
<Ellipse Canvas.Top="20" Canvas.Left="40" Width="40" Height="40" Fill="Gray"
Margin="0,-40,0,0"/>
or an appropriate RenderTransform:
<Ellipse Canvas.Top="20" Canvas.Left="40" Width="40" Height="40" Fill="Gray">
<Ellipse.RenderTransform>
<ScaleTransform ScaleY="-1"/>
</Ellipse.RenderTransform>
</Ellipse>
In order to invert the y direction of the whole Canvas coordinate system, you may apply a RenderTransform to the Canvas:
<Canvas ... RenderTransformOrigin="0,0.5">
<Canvas.RenderTransform>
<ScaleTransform ScaleY="-1"/>
</Canvas.RenderTransform>
...
</Canvas>
Edit: You may also put the Ellipse in another Canvas with zero Height, and attach it to the lower Canvas border:
<Canvas Canvas.Top="20" Canvas.Left="40" Width="0" Height="0">
<Ellipse Canvas.Bottom="0" Width="40" Height="40" Fill="Gray"/>
</Canvas>
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?
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>