stretch canvas on maximize - c#

(Can't add pictures so I'll try and explain it) So my program basically consists of two parts: a bitmap image that is scanned and shown in the main window (on a canvas), and a canvas derived class I made that basically takes data (b&w values ranging from 0-255) from the image and represents it in a histogram format (a bargraph basically) and it overlays the bitmap image (its transparent so you can still see the image).
Alright so I got my program working, the only problem is my canvas derived class wont stretch until I "refresh" the screen. The children of the class (being windows shapes rectangles) wont stretch with the window.
It looks fine up to this point
but then I maximize it...
The rectangles then just stay exactly where they're at. It isn't until I click the "display histogram" button that it will disappear and then after clicking it again, I get...
...Exactly what I want, the histogram is in the right place on the screen. So here's my question, how can I get the histogram to stretch with the main window? instead of having to refresh it every time?
<Border Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="3" BorderBrush="Black" BorderThickness="5" x:Name="testview">
<local:DrawingCanvas x:Name="pbHistogram" IsHitTestVisible="False"
Width="Auto"
Background="Transparent"
Height ="{Binding Path=ActualHeight, ElementName=testview}"/>
</Border>

I know this is not really an answer, but I think the problem is the canvas class itself. It has no automatic layouting or resizing of its child elements. Link to msdn: http://msdn.microsoft.com/en-us/library/ms609101(v=vs.100).aspx
What you could try is to hook up to your main window's resize event and call the same function that the buttonpress calls.

Maybe the quickest, easiest way to do this would be to put your canvas in a Viewbox.

Related

WPF stretch image without Stretch="Fill"

I am trying to make responsive WPF app which shows image. One of the program's functionalities is selecting a piece of an image by clicking and draging the mouse. I use Point p = e.GetPosition((IInputElement)sender); to find cursor position, and I found out I cannot use Stretch="Fill" because it causes the MouseUp cursor to select a little lower than it should and MouseMove is also inaccurate (I have to drag the mouse a lot further than I should). On the internet, I found the reason for this behavior that you cannot use Fill and have to use None instead. However, the image is much smaller without Fill.
This is my XAML:
<Grid Grid.Row = "1"
Grid.Column="1"
HorizontalAlignment="Left"
VerticalAlignment= "Top"
Margin="0,30,0,0">
<Image x:Name= "image1"
Grid.Row = "1"
Grid.Column="1"
Cursor="Cross"
MinWidth="300"
MinHeight="300"
MaxWidth="512"
MaxHeight= "512"
Stretch = "None"
RenderOptions.BitmapScalingMode="NearestNeighbor"
RenderOptions.EdgeMode="Aliased"
VerticalAlignment="Top"
MouseDown="picOriginal_MouseDown"
MouseMove="picOriginal_MouseMove"
MouseUp="picOriginal_MouseUp" />
</Grid>
I don't know how to embed my image so that in the window view it fills the grid without this Fill property and at the same time is responsive for fullscreen. Should I wrap Image with something else from the WPF toolbox?
I find it easier using the background of the picture box to be the image then use the stretch in that. Alternatively, you could use the image with any of the other options, try using the the properties tab, here are the other stretch options tho: None, Fill, Uniform, UniformToFill
Tell me if this helps, tryna get rep, thanks!

how to overlay an image over an image in WPF?

I'm trying to figure out how to overlay an image or textbox over an image in WPF. The base image will be hosting a video feed from a Kinect sensor and I want to overlay an image on it. For example the video feed will have a textbox on the feed that will update a counter or an image of a tree on top of the video feed.
Is there a straightforward way of achieving this in the layout? Is it just a matter of changing properties or adding a canvas?
The below picture better illustrates what it is I'm trying to do:
You can use two transparent canvas inside the Grid without any row and column then place your objects in Back and front Canvas accordingly they will overlap
that is:
<Grid>
<VideoControl><!-- I've never tried video --></VideoControl>
<TextBlock Text="My Text" />
</Grid>
Usually you specify <Grid.ColumnDefinitions> and <Grid.RowDefinitions> but since you do not du that here the controls will overlap
HTH
The usual way for me to overlay items in WPF is just to put all of the elements in a Grid. If you do not define any Columns or Rows the elements will overlap.
Example
<Grid>
<Image Source="image on lowest layer" />
<Image Source="overlaying image" />
</Grid>

Canvas Drawing creating System.OutOfMemoryException Win Phone 8

I am developing a windows phone 8 app, I use Rectangle and Lines to draw a graph inside a Canvas placed inside a ScrollViewer.
But during the drawing I am facing System.OutOfMemoryException during drawing of the canvas( graph may go more than 3 times the size of the screen)
I have placed the Canvas inside a ScrollViewer. When I remove the ScrollViewer the issue does'nt occur but I am unable to scroll the Canvas even if I set the property Scrollviwer.HorizontalScrollBarVisibilty = Visible.
<ScrollViewer Name="MainScrollViewer" VerticalScrollBarVisibility="Disabled" HorizontalAlignment="Stretch" HorizontalScrollBarVisibility="Auto" Grid.RowSpan="2" >
<Canvas x:Name="MainCanvas" HorizontalAlignment="Left" Tap="OnCanvasTap" >
<Canvas.RenderTransform>
<CompositeTransform CenterX="100" CenterY="75" />
</Canvas.RenderTransform>
</Canvas>
</ScrollViewer>
I have also tried using GC.Collect and Canvas.Children.Clear() where I am drawing but even then the issue persist.
Instead of using a large canvas inside a scrollable div to contain all of the graphics you can use a smaller canvas, optimally max of the actual screen size (not the graphics) and then use translate the canvas and redraw the graphics at the translated position.
Optimally because if you have a huge canvas and only see 25% of then the other 75% is wasted memory.
By using the canvas as a "peephole" combined with translation you will get the same result on screen (you see 100% of what is possible to see at one time) and you don't need to worry about your graphics as this will be clipped automatically by the canvas.
You can attach translation to mouse/touch drag-and-move operation or make "virtual" scroll-bars if that is preferred.

ScrollViewer's ScrollToHorizontalOffset not working in Windows 8 app

I have a Windows Store app with a ScrollViewer and an Image in it. When i double tap on the ScrollViewer I want it to zoom the Image to its width. This part is not a problem but I also want the Image to be centered after it has beed zoomed in.
I tried calling the ScrollToHorizontalOffset method on the ScrollViewer but It does not seem to work with any number I give it. What is the problem?
Perhaps the offset only works for the non-zoomed view where your image fills the ScrollViewer completely and thus can't be scrolled. You could try setting the image dimensions so that it is larger than the ScrollViewer, but set original ZoomFactor, so that it fills the ScrollViewer at first. Then zooming and scrolling might work.
Assign a SizeChangedEvent in the scrollviewer.
<ScrollViewer SizeChanged="OnSizeChange"></ScrollViewer>
like this. Then it is better to place your image inside a canvas. So your code will be probably like this.
<ScrollViewer SizeChanged="OnSizeChange" x:Name="scrl">
<Canvas RenderTransformOrigin="0.5,0.5" x:Name="main">
<Image source="" Canvas.Top="insert desire double value here", Canvas.Left="Same goes here"/>
</Canvas>
</ScrollViewer>
then in the code behind you can change the height and width of your canvass depending on the scroll viewer
Main.Width = scrl.ViewPortWidth;
Main.Height = scrl.ViewPortHeight;
You can experiment on the size of the canvass while adding a double tap event to it. Changing the size of the canvas can zoom in or out the image because the image is inside the canvass
Try with 'ChangeView' instead of 'ZoomToFactor'

How do I handle a requirement to put a magnifying glass feature onto my Silverlight app?

How do I handle a requirement to put a magnifying glass feature onto my Silverlight app?
It is not as easy as one might think.
The previous programmer did it and thought it looked cool.
It works by manipulating the scaling operation. It is a lot like the zoom feature in a browser.
Anyway, in my program it requires I change the Z level of some of the objects so that they appear on top of other objects in the window. How do I do that?
The problem is that I have a grid with two rows. Naturally, in XAML, whatever is listed last, appears "on top" of whatever is described at the top of the XAML page. Does this make any sense? If the components in the top part of the grid are scaled up, they hide behind the bottom row. I don't want that.
You can achieve a magnifying glass effect by having two Image objects. The first object contains the original image, the second image has a scale transform and clip geometry applied to it that simulates the magnifying glass. Then as the mouse moves, you need to manipulate the clip geometry, the left and right coordinates of your image. Here is some XAML code that shows the effect I am talking about
<Image Width="640" Height="480" Source="myImage.PNG"/>
<Image Canvas.Left="-500" Canvas.Top="-380" Width="640" Height="480" Source="myImage.PNG">
<Image.RenderTransform>
<ScaleTransform ScaleX="3" ScaleY="3"/>
</Image.RenderTransform>
<Image.Clip>
<EllipseGeometry RadiusX="40" RadiusY="40" Center="320, 240"/>
</Image.Clip>
</Image>
Also, if that's not enough, here is a tutorial on how to do a magnifying glass effect. And here's yet another tutorial.

Categories