my current free-time project, in order to dive into WPF MVVM, is a "digital" copy of an old puzzle I used to play a lot in my childhood. It basically is a simple puzzle where one has to fill a given space with different kind of pieces so the whole space is filled. But with the extra twist of being in hexagonal space.
Just to illustrate, this is what it currently looks like in WPF:
http://img190.imageshack.us/img190/2553/atomgridmolecule.png
So basically there is a number of predefined pieces(like the orange one above) which can be "plugged" into the given grid(the gray stuff above).
So the result might look something like this:
http://img30.imageshack.us/img30/2553/atomgridmolecule.png
I want the user(probably only me^^) to be able to drag and drop the pieces into the grid. I want the dragging to look natural meaning having the correct offset while dragging depending on where the user clicked the piece.
Both grid and molecule are the same control, a custom hexagonal panel control derived from the WPF Panel class.
The problem is on how to do the "plugging in" and especially the "unplugging".
I have two ideas on how I might tackle this:
Just color the cells in the grid and hiding the original piece
Pro:
Zero cost perfect alignment of the cells
Cons:
Recreating the piece at the right spot with the correct mouse offset if dragging out, seems impossibly? hard to do
Snapping the piece to the grid and show it on top
Pro:
Dragging out is a simple dragging operation, just as dragging in
Disadvantage:
Somehow have to align the piece with the underlying grid, some kind of snapping
So which approach should I take? Even more important how can I even implement this in WPF? Especially using a clean MVVM way.
Thanks so much for your help! Any input is highly appreciated!
EDIT:
Thanks Aran, I thought so too.
But how do I actually implement this now?
How can I actually get the coordinates?
All the orange circles are linked, so how can I "move" or better "plug" them in as one piece?
Im inclined to go with the second idea. a simple snapping would just be to test if the centre point of the circle you are dragging is within some tolerance factor of a circle on the grid and if so snap them.
Related
I started my app by placing rectangles and other objects on a stackpanel. That worked will until I wanted to split my rectangles and have two columns of rectangles. The vertical stackpanel worked well until I needed to split my rectangles into two columns and put stuff on the left and stuff on the right.
So I converted to a canvas. Now
mainCanvas.Children.Add(grid); // seems to replace what the last Add placed on screen. Any ideas how to control the position of items added to the canvas?
Edit:
Ok clearly a canvas is the wrong panel to use. Two column's of stackpanel's might be made to work. But when I look at what I am actually trying to accomplish, the column's aren't limited to two, but could be n number of columns. Why? Because the application is a flowchart style app that builds a custom language script. The diamond decision shape splits one column into two which can split into two more extra.
I wonder about using a single stack panel and just making a grid with multiple grids horizontally in it. But mouse events would have to be smart enough to know which grid in the grid your actually in. Not undoable I think, but not trivial...just looking to see if there is a obvious use this choice that i am missing by being a wpf rookie.
Edit2:
The issue I have with just using a grid is that when the window is stretched a
grid does not resize to the new window size.
making a grid of multiple other grids, then using isMouseOver to test to see which grid in the single child of the stackpanel actually needs mouse highlighting works.
I'm creating a game that first requires the user to drag a certain textblock into a rectangle. Depending on which textblock is dropped into the rectangle, I want to store the contents of that specific textblock. It's important to note: I want the values stored only when the textblock is dropped inside the rectangle.
The problem: How can I make it so the computer knows that the rectangle contains the textblock?
Here's a screenshot to make things a little more clear: http://gyazo.com/3aa3a8678f11260889261fcd46366616.png
As of now, I can drag and drop the textblock fine, but the computer has no way of knowing if the textblock and rectangle intersect.
I've been trying to solve this problem for a few days now, and have spent a lot of time trying to use the system.drawing.rectangle.IntersectsWith()...only to find out that you can't dynamically add a system.drawing.rectangle to the canvas.
I've also thought of doing it by coordinates: if(textblock's coordinates are within the bounds of the rectangles coordinates)... However, I've spent time trying to figure out how to dynamically get the coordinate position of a xaml control, only to find out that you can't.
Could someone please offer some guidance? I've been working hard towards this and I've hit a dead end, so any degree of help will be great.
Thanks!
summarizing I have implemented a chart control as a simple Canvas with a Polyline on it. The next thing I need is to be able to zoom the chart.
I would like to know how would you that (just the idea, no details needed). What I would like to do is to create somehow a bigger Canvas and paint the line bigger and just show a part of the Canvas to the user, and the he drags the Chart it will move the Canvas. Something like in the following picture. Do you think this is possible?
Kael Rowan from Microsoft Research built a ZoomableCanvas class that may do exactly what you want. You can also see all the posts he wrote about it. You can even try a running XBAP example if your browser supports it.
We use the RenderTransform for this, create your zoom and pan matrix( or transform ) and apply that to your canvas. The nice thing is, that you can still have elements that can display behind or on top of the canvas with the identity transform or with another. For example for a grid or screen space elements like a minimap, which should always be visible. You might also want to look into this old question, which is somehow related.
I have a Canvas based custom control that enables selection, dragging and resizing of visual children. I have so far Lines, Rectangles (without background) and images. Problem is, for selection, lines for example are hard to select obviously as they are 1 pixel high. Could you suggest a way to make them easily selectable? I'd like something along the lines of Visual Studio's selection, in which there are some pixels of "miss tolerance" when selecting something thin like a grid, you don't need to hit the exact pixel the line is at, few pixels around it are just as good, but I'm not sure how to implement that in WPF. Please help?
Thank you.
Perhaps what you are looking for can be easily achievable by using Adorner
I'm new to C# and I've been working on a small project to get the feel with Visual Studio 2008. I'm designing the GUI in C#, and I have a TabControl with three GroupBoxes. These three GroupBoxes are anchored to the left and right of the screen and work perfectly when resized horizontally.
I would like these three boxes to take up 33% of the height of the screen, and gracefully resize. I've tried messing around with anchoring, but I can't seem to find the answer. I've also been searching for something similar, but unfortunately, searching for positioning containers yields all CSS and HTML stuff.
This seems like a pretty common thing to do, but I can't seem to find an easy to way to do it. If someone could point me in the right direction, I'd greatly appreciate it.
Thanks!
Try out the TableLayoutPanel. I believe it does exactly what you want. It allows you to define columns and rows within its area, specifying their width (for columns) and height (for rows) in percentages or pixels. You can then drop a group box into each cell and set its Dock property to Fill, and it will nicely resize along with the cell when the TableLayoutPanel resizes (which can be easily achieved by using docking or anchoring).
This is really a shot in the dark but maybe you could try using split-panels ?
Edit: I've just checked in Visual Studio and I think the TableLayoutPanel might do what you want.
Edit2: dang, beaten to the punch :)
Handle the form's Resize event: Add code to compute the new size/position of the controls in there. Beware to interferences with the controls' Anchor property. You may have to Anchor to None and compute left and right position yourself as well.
Since you're learning, I guess you prefer not to receive a full solution but rather a direction. No code from me then ;-)