WPF - positioning with dynamically canvas - wpf

I have the following code:
<Grid>
<Canvas Grid.Row="0" x:Name="drawingSurface" Background="White" ClipToBounds="True"
MouseLeftButtonDown="drawingSurface_MouseLeftButtonDown"
MouseLeftButtonUp="drawingSurface_MouseLeftButtonUp"
MouseMove="drawingSurface_MouseMove">
</Canvas>
<Grid Name="pnlProperties" Visibility="Hidden"/>
</Grid>
After starting this window, the user selects his interested area (I catch MouseMove, MouseLeftButtonDown, MouseLeftButtonUp).
Then I want to show the panel pnlProperties under the selected area in the left corner (in my interested coordinates).
How can I do it?

Put the Grid into the Canvas, and then set the coordinates for the Grid, using:
YourCanvas.SetLeft(pnlProperties, MOUSE.X)
YourCanvas.SetTop(pnlProperties, MOUSE.Y);

Related

Marquee/Rectangle Selection of buttons in UniformGrid

I've programmatically generated buttons in a UniformGrid i.e. 4 rows and 4 columns, so 16 buttons.
I want to be able to click and drag to create a rectangle box to select a box of buttons.
Is this possible?
Trying to use this example currently but not seeing the drag box appear
Click and drag selection box in WPF
Currently, since it's all programmatic, the UniformGrid code in XAML is this:
<Canvas DockPanel.Dock="Top" Name="buttonCanvas" Width="800" Height="400">
<Rectangle x:Name="selectionBox" Visibility="Collapsed" Stroke="White" StrokeThickness="4" />
<UniformGrid DockPanel.Dock="Top" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" x:Name="uniformGrid" Grid.Row="1" Width="800" Height="400"
Rows="{Binding RowNums}"
Columns="{Binding ColumnNums}" MouseDown="uniformGrid_MouseDown" MouseUp="uniformGrid_MouseUp" MouseMove="uniformGrid_MouseMove" Background="Transparent">
</UniformGrid>
<!-- This canvas contains elements that are to be selected -->
</Canvas>
Start by drawing a Canvas over the UniformGrid:
<Grid>
<UniformGrid>
<Button/>
...etc....
</UniformGrid>
<Canvas/>
<Grid>
Then you would by handle the mouse down, mouse move and mouse up events for the canvas. In mouse down you would add a rectangle to the canvas as the current mouse pos, in the mouse move you would resize the rectangle based on the current mouse pos and work out which buttons were enclosed by the rectangle and set them to be "selected" by binding to a view model somewhere. In the mouse up you would remove the rectangle. You would have some kind of trigger in a style to set the style to be different when selected

How do I properly draw and scale a Canvas as a WPF background to a control?

I have a StackPanel that needs to contain drawn background. Specifically, my StackPanel needs to have the ability to grow and the rectangle must grow with the StackPanel, but must remain pseudo-anchored to each side at a fixed position.
I've attempted to use the Canvas.Left, Canvas.Right, Canvas.Top and Canvas.Bottom attached properties, but so far they've not worked. Furthermore, this does seem to work when drawing within Canvas objects, just not when they are embedded within a VisualBrush set as a background. How can I accomplish drawing this resizable, rectangular background within my StackPanel?
Below is the state of my current code. I've tried various approaches but none seem to work.
My Code:
<StackPanel DockPanel.Dock="Right" Orientation="Vertical" VerticalAlignment="Center">
<StackPanel.Background>
<VisualBrush Stretch="None">
<VisualBrush.Visual>
<Canvas Background="Magenta" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
Rectangle Fill="#FFDDECF7" Canvas.Left="20" Canvas.Top="20" Canvas.Bottom="20" Canvas.Right="0"/>
</Canvas>
</VisualBrush.Visual>
</VisualBrush>
</StackPanel.Background>
...
</StackPanel>
This currently doesn't render anything. I set the canvas background to magenta just so I could see if it were drawing, and I'm not even seeing that. Other attempts have drawn the canvase, however, the blue rectangle is always stretched to fill the window, regardless of attached canvas property settings.
Sample:
The image below is a sample of what I want. Again, I'm using an ugly Magenta color to show the offset of the internal, blue rectangle. As the StackPanel grows or shrinks, the rectangle needs to be affixed to the top, left, right and bottom.
My suggestion is to place the stackpanel inside a grid:
<Grid DockPanel.Dock="Right" VerticalAlignment="Center" Background="Magenta">
<Rectangle Margin="20" Fill="#FFDDECF7"/>
<StackPanel Orientation="Vertical">
no background...
</StackPanel>
</Grid>
Wrap Canvas into a ViewBox, then work on a ViewBox. As far as I know Canvas doesn't support scalling too well.

How to show scrollbars for the canvas wpf

I implemented the canvas from the code project example Drag controls in canvas
Here user has the ability to move anywhere in the canvas, when control reaches top or bottom, i want to show the vertical scrollbar. How can I make this work?
<ScrollViewer VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Visible">
<Grid Name="grid">
<Canvas Name="canvastoExport" >
<Polygon Points="200,100,300,100,300,200,200,200" Fill="Green"></Polygon>
</Canvas>
</Grid>
</ScrollViewer>

Dynamic size canvas with Scroll bars

I am developing a simple WPF application without any auto layout. The goal is when a user clicks (mouse down) a element (say textBlock) will appear at the location of the mouse click. For this I am using canvas panel embedded in a Grid of 1 row, 1 column and scrollviewer (visible). The issues are:
1. when the application window is resized the scroll viewers do not become active.
2. I want the ability to auto grow the canvas with mouse drag. Something like in MS-Excel when user drags the mouse horizontally/vertically the canvas should grow.
I have searched net a lot to figure this out and am unable to get an answer. Any help in this regard would be great.
Thanks a bunch in advance.
-P
I after asking this question I figured it out how to have freeform layout and autosize. Here is a sample XAML if anyone needs it or has better suggestion to improve this:
<Ellipse Grid.Column="0" Fill="Red"/>
<GridSplitter Grid.Column="1" HorizontalAlignment="Stretch"/>
<!-- Creating a grid with one row and one column"-->
<ScrollViewer x:Name="ServerLiistCanvasScrollViewer"
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto"
Height="Auto" Width="Auto"
Grid.Column="2" >
<Grid x:Name="drawingGrid" Grid.Column="2"
VerticalAlignment="Stretch" HorizontalAlignment="Stretch"
Background="Pink"
MouseDown="handleCanvasMouseDown">
</Grid>
</ScrollViewer>
</Grid>

Perfect Center on WPF Canvas

Since the canvas requires a Top/Left for placement, if you want to center something, is adding a grid at the proper Canvas.Top with HorizontalAlignment="Center" the best way to do it, or is there a better way?
This snip is a 150X300 canvas, with some content centered in a grid ....
<Canvas Width="150" Height="300">
<Grid Canvas.Top="75" Width="106" HorizontalAlignment="Center">
{whatever you want centered}
</Grid>
</Canvas>
Guy's solution works, but you may have to tweak z-order and visibility if you're juggling hit testing.
Another alternative is having the Grid inside the Canvas (as you've specified in your XAML) with the Height/Width set to (or bound to) the Height/Width of the Canvas. Then setting HorizontalAlignment/VerticalAlignment to Center for the contents of your Grid.
I'm not sure if this will meet your exact requirement, but if you put both the canvas and the content inside a grid as peers, it will get you a centered result:
<Grid>
<Canvas Width="150" Height="300"/>
<Button HorizontalAlignment="Center" VerticalAlignment="Center" Width="106" Content="Click"/>
</Grid>

Resources