Move Image control in VB2010 WPF - wpf

In windows forms, you can easily change the ".left" value of a picturebox to move it. However, I have noticed that in VB2010 WPF, this is not the case.. Can anyone show me how to change an image control's .left (or equivalent) value in wpf?
Thanks
Nick

Normally placement in WPF depends on the container a control is a child of. If you want to adjust placements you can either use the Margin property which should work for almost all containers or place the Image in a Canvas, then you can use the Canvas.Left attached property for placement.
Additionally you could use LayoutTransform or RenderTransform properties to move your control around; you would use a TranslateTransform for that.
e.g.
<Grid>
<Button Margin="20,0,0,0" Content="Using Margin"/>
</Grid>
<Canvas Height="30">
<Button Canvas.Left="20" Content="Using a Canvas"/>
</Canvas>
<Grid>
<Button Content="Using TranslateTransform">
<Button.RenderTransform>
<TranslateTransform X="20"/>
</Button.RenderTransform>
</Button>
</Grid>
(Changing margin programmatically:)
Thickness margin = Control.Margin;
margin.Left += 1;
Control.Margin = margin;

Related

Adding a border to image control prevents image from displaying WPF

I have a perplexing problem that makes no sense to me - I am trying to place a border round an image control in WPF. The image control displays an image perfectly (I have loaded through code behind and XAML and both work fine). However when I place a border around the image control the image does not appear at all. This happening with three image controls all with identical config. Does anyone know why this is or how I can fix it? Many thanks, Jeff.
XAML (with border commented out) is below:
<!--<Border BorderBrush="Black" BorderThickness="2" Margin="201,172,618,450" Grid.Column="1">-->
<Image Name="imgFault11" Stretch="Fill" Grid.Column="1" Margin="200,172,619,450">
<!--</Border>-->
You are putting both in Grid.Column="1"
Put the image in the border
Start with no margins
<Border BorderBrush="Black" BorderThickness="2" Grid.Column="1">
<Image Name="imgFault11" Stretch="Fill">
</Border>
You may have to send the border to the Background. Once you add this it overlays the image. Right click the border .. go to order and then choose "Send to Back". The border control is in the toolbox. This is all a little messy though as getting the border to match the image box size takes time to get right and then you have one control on top of another..etc.

Positioning an element inside the Canvas by its center (instead of the top left corner) using only XAML in WPF

The common question about positioning an element inside a Canvas is "How to position the center of element (instead of the top left corner)".
WPF: Resizing a circle, keeping the center point instead of TopLeft?
WPF Center Ellipse at X, Y
WPF element positioning on a Canvas
Several solutions are presented, but they all have drawbacks.
The easiest solution is to accommodate the element size during while setting the Canvas.Left and Canvas.Top properties programmatically. This works, but only once. This solution doesn't support bindings and it will break when the element size is changed. You also cannot set the Canvas.Left or Canvas.Top using
Another set of solutions involve translate transformations utilizing either RenderTransform or Margin. These solutions require binding some property to the -0.5 * Width or -0.5 * Height. Such binding requires creating a custom ValueConverter and is impossible to create using only XAML.
So, is there a simple way to position an element inside canvas so that its Canvas.Left and Canvas.Top correspond to the element's center and both size and position properties can be bound to some other properties?
XAML and bindings seem very powerful, but sometimes there are simple problems that require very complex solutions. In my bindings library creating such binding would be as easy as writing element.Center = position or element.TopLeft = position - element.Size / 2, but don't let me get carried away.
I've found a very simple solution which uses only XAML and supports binding both size and position properties of the element. It seems that when the WPF control with alignment set too Stretch or Center is placed inside the canvas, the element "gravitates" towards centering as the (Canvas.Left, Canvas.Top) point (the state that we desire), but is stopped by the "angle plate" placed at the same (Canvas.Left, Canvas.Top) point. How do I know about this "gravitation"? It's evident when you ease the block by setting the Margin of the element to a negative value. Setting the negative margin allows the element to move towards its center goal. The element moves until the Margin reaches (-Height / 2, -Width / 2) so that the element becomes perfectly centered at the (Canvas.Left, Canvas.Top) point. Further changes don't cause any movement since the element is already perfectly positioned.
Solution: set Margin="-1000000".
So in the following code the ellipses are both centered at the (200, 200) point. The first ellipse has Left and Top properties corresponding to the ellipse center allowing to easily bind them with some other objects' properties.
<Canvas>
<Ellipse Width="100" Height="100" Canvas.Left="200" Canvas.Top="200" Opacity="0.5" Fill="Red" Margin="-100000" />
<Ellipse Width="100" Height="100" Canvas.Left="150" Canvas.Top="150" Opacity="0.5" Fill="Blue" />
</Canvas>
The bad thing is this solution only work in WPF. Silverlight and WinRT don't have the described behavior.
Even simpler, at least for Shapes, would be to use a Path with an appropriate Geometry:
<Canvas>
<Path Canvas.Left="200" Canvas.Top="200" Fill="Red" Opacity="0.5">
<Path.Data>
<EllipseGeometry RadiusX="50" RadiusY="50"/>
</Path.Data>
</Path>
</Canvas>
I solved this by putting the canvas into the bottom-right cell of a 2x2 grid. That makes the 0,0 coordinate the center of the grid, and then you can do all your drawing relative to that.
This solution worked for me Center text at a given point on a WPF Canvas. He uses a MultiBinding and a custom Converter to adjust the margin on his element. Brilliant!

How to create stretching clipping rectangle in Silverlight

Since Silverlight doesn't have the comfy feature of 'ClipToBounds' properties on controls, I have to define clipping shapes by myself. I was wondering if I could create a clipping rectangle that's following the size of my control. Any suggestions?
If there is an existing control in you layout that you want to dynamically clip then use its SizeChanged event. For example lets say you want to clip this Grid:-
<Grid SizeChanged="Grid_SizeChanged" Width="50" Height="20">
<Grid.Clip>
<RectangleGeometry />
</Grid.Clip>
<TextBlock Margin="0 -9 0 0" Text="This text should not be legible" />
</Grid>
With the code-behind:-
private void Grid_SizeChanged(object sender, SizeChangedEventArgs e)
{
((RectangleGeometry)((Grid)sender).Clip).Rect = new Rect(0.0, 0.0, e.NewSize.Width, e.NewSize.Height);
}
For a your own custom control you might consider handling the clip rectangle in the ArrangeOverride instead of relying on the SizeChanged event. In this case you probably want to assign RectangleGeometry to the Clip property in code rather than relying on it being assigned in the Xaml of the default template.
Silverlight supports that:
try using HorisontalAlignment and vertical alignment propertys. Set them to stretch.
If this doesn't work then you will have to post xaml example.

In a WPF user control, how do I specify coordinates relative to the control's total size, so that the control will scale correctly?

I have created this simple expand button user control with WPF:
        
I designed the thing with Width and Height both set to 100 so that I could see what I'm actually doing. The stripped-down XAML of this user control is:
<UserControl x:Class="Foobar.ExpandButton"
...
Width="100" Height="100">
...
<Border>
...
<Canvas>
<Line ... X1="20" Y1="20" X2="50" Y2="50"/>
<Line ... X1="80" Y1="20" X2="50" Y2="50"/>
<Line ... X1="20" Y1="50" X2="50" Y2="80"/>
<Line ... X1="80" Y1="50" X2="50" Y2="80"/>
</Canvas>
</Border>
</UserControl>
Eventually, the button should be able to dispay correctly at various sizes, e.g. at 20 × 20 points. However, due to the coordinates used with the Line elements, I cannot just insert this user control in another window like this:
<foobar:ExpandButton Width="20" Height="20" /> <!-- doesn't scale correctly! -->
I could apply a LayoutTransform → ScaleTransform each time that I use the element at another size than its default 100 × 100 points, but there has to be a better solution.
How can I define the lines' coordinates such that they are relative to the user control's total size?
You can put the image inside a view box, or inside a VisualBrush and use a rectangle to draw it (set the brush to the Rectangle.Fill property).
Even better, convert your image to a Drawing objects (replace Canvas with DrawingGroup and the shapes inside it with GeometryDrawing) and use DrawingBrush to paint it.

WPF. How to show only part of big canvas?

Lets say I have a canvas defined to be 1000x1000 big. Is it possible to only show a 100x100 part of it in a Viewbox(or a rectangel)?
Any help is apreciated.....
If you work with Brushes, you might want to take a look at Viewbox and Viewport in WPF
Edit: I just realised that Viewbox and Viewport are used for Brushes
This is not really appropiate in your situation. I looked it up, and I think you will like the Clip property on UIElement.
Since Canvas is also a UIElement, you can use the Clip property to simulate a viewport on your Canvas..
Click here for some simple Geometry types
I think you would suffice with a RectangleGeometry
<Canvas>
<Canvas.Clip>
<RectangleGeometry Rect="50,50,25,25" />
</Canvas.Clip>
</Canvas>
Edit #2:
Hehe ok.. if you want your total Canvas displayed, only smaller, perheps you should take a look and LayoutTransform. Then use a ScaleTranform to resize your Canvas ;).
<Canvas>
<Canvas.LayoutTransform>
<ScaleTransform CenterX="0" CenterY="0" ScaleX="0.5" ScaleY="0.5" />
</Canvas.LayoutTransform>
</Canvas>
Tweak the parameters until you receive the desired effect ;)

Resources