This is more of a "Is it possible (with a reasonable amount of time and work)" than a "how exactly is it possible" question. I'm getting into WPF at the moment and am interested in graphical applications in an MVVM approach. In the meaning of an ms-paint like application. Now I see that and how I can draw e.g. a ractangle on a canvas, store those rectangles in a list etc.
But I am wondering if I can do that more advanced. For example extend the rectangle so I can give it more infos (I can't extend the rectangle itself since it's a sealed class), have existing shapes on the canvas able to drag them around, make the shapes complex (e.g. I double click one to open a new Window that represents the "inside" of that shape) etc.
Is such an application possible with a reasonable amount of work and time in WPF or would I rather use some different library/framework for this?
Yes, It is possible, Actually, you are listing CAD specifications, In fact, I work on this type of technology, so I'll suggest you some resources to have a clue..
Take a look at this project(WPF, 2D)
And this one(WPF, 3D)
And this one(WPF, 2D)
The previous projects are WPF-based, also, you might host a WinForm control in your WPF app, take a look at this one(WinForms, 2D)
If you change the specification a bit and say: "I don't want to edit the drawings on the canvas", then you could go with this option: convert your shapes to PathFigureCollection and EllipseGeometry objects, then construct Paths from these objects and add the Paths to the Canvas, this is a pure WPF approach. Indeed, you can add traditinal controls like TextBlocks as children to your Canvas, I have done such one like this..
Hope it helps.
Related
I am trying to create a WPF application using C# to run on Pixelsense that is basic version of the tangram puzzle. I am able to draw my 7 shapes and translate and rotate them all around the screen.
Could anyone give me advise regarding how I should go about saving the pattern (with shapes in specific positions and orientations) so that when a user creates the pattern next time, the application can match it to the saved one and tell the user if it's correct.
It's a pattern matching and recognition problem that I am trying to solve.
I have been stuck on this for a while now :(
Define the solution as a collection of objects with shapeType, position, and orientation properties. Have the solution include one shape at position 0, 0 and an orientation of 0. Now loop over all the shapes the user has actually placed to find the ones with a shapeType that matches the shape your solution has at 0,0,0. Calculate the position and orientation of every other shape relative to where the user put this one. Compare those values to the rest of your solution. You'll need to experiment with how much tolerance to allow because this stuff is not precise - to make the game fun, err on the side of having high tolerances. If needed, you can follow this up with some performance optimizations to only re-evaluate pieces that moved.
Hopefully you are using physical shape prices with tags on them instead of this purely a virtual game. I always wanted to build this when I was on the Surface team but it never happened. One challenge you will run into is defining how the tag's position/orientation relates to the actual shape. If you'll be putting tag stickers on multiple tangram sets, you almost certainly won't get the on precisely the same each time so you may need to add a "calibration" mode to your app (have the user place each piece in a specific spot and then push a button so you can record where the tag is relative to those spots). The TagVisualizer WPF control should help a lot for building your UI - definitely look into using it (this scenario was top of mind when we designed that API). The default behavior of that control (if you tell it the ID of a tag to look for but not how to visualize it) is a "crosshair" that can help you find tune your offset values.
Good luck! If you wouldn't mind recording a YouTube video when you are done and posting a comment here linking to it, I'd really appreciate that
You can use ObservableCollection or List of a custom class. That class can consist of various values such as position, orientation etc as properties.
When a new pattern is drawn or when the pattern change its position you can update that particular object stored in the collection. As you have all the details of the pattern(positions and orientation) you can iterate the for loop and check the position of the new pattern when added.
I am not sure if this is the right place to ask for such concept information advice, so I apologise if it's unrelated or off-topic to ask in Stack Overflow.
I want to develop an application in WPF which has the ability to draw polygons with the functionality of a regular control, they may change shape by adding, removing or moving vertices, change brushes all by run-time, from data-binding or perhaps direct manipulating from C# code (still not sure about that).
What I am trying to achieve is an application which draws a map and the shapes on it are the entities with the dynamic borders over the map (for instance say political borders). The polygons also have to be clickable controls with collision test (not just a bounding box, but exactly by the shape of the entity on the map). I can expect the shapes to be very detailed because of borders which found by rivers and mountains or other natural objects which not just a straight line of two vertices, so it's performance should be an important factor here because one polygon may contain hundreds of vertices).
What I've concluded that it is possible to achieve via WPF such an application. But my uncertainty is on the most efficient way to implement the map drawing, perhaps I should implement D3D hosting like SharpDX but I don't want it, it would make things even more complicated and difficult.
I prefer everything in this map to be functional as a regular WPF control with it's data-binding and stylising abilities. I've developed with WPF some several small test projects for months to learn the basics and its main concept. But now comes the main interest of mine to develop with WPF. I need some advice please, because drawing complicated and dynamic shapes is still not really clear to me to just go on and start develop it.
I would use WPF, indeed I would say WPF is perfect for this, though there will be considerable amount to learn. WPF uses DirectX so is preformant enough I imagine (provided you have the hardware).
You will need to become familiar with:
UserControl
DependencyProperties
Polygon
Canvas
However if you are not already familiar with Dependency Properties, they can be a headache to learn, so rather than creating your own UserControl with them, you can get away with a Canvas in your Window and build things programmatically or at design time in XAML.
As for actually drawing shapes; if you know ahead of time what the shapes will look like you can draw them ahead of time using tool like Blend (or by yourself in XAML - you will need to become familiar with the Path Markup Syntax) then you can use transforms such as a ScaleTransform to transform them at run-time, or if you want to build them at run-time you can do so programmatically adding points to a Polygon
e.g. from (Polygon)
//Add the Polygon Element
myPolygon = new Polygon();
myPolygon.Stroke = System.Windows.Media.Brushes.Black;
myPolygon.Fill = System.Windows.Media.Brushes.LightSeaGreen;
myPolygon.StrokeThickness = 2;
myPolygon.HorizontalAlignment = HorizontalAlignment.Left;
myPolygon.VerticalAlignment = VerticalAlignment.Center;
System.Windows.Point Point1 = new System.Windows.Point(1, 50);
System.Windows.Point Point2 = new System.Windows.Point(10,80);
System.Windows.Point Point3 = new System.Windows.Point(50,50);
PointCollection myPointCollection = new PointCollection();
myPointCollection.Add(Point1);
myPointCollection.Add(Point2);
myPointCollection.Add(Point3);
myPolygon.Points = myPointCollection;
myGrid.Children.Add(myPolygon);
I'm working on a Add-in for PowerPoint 2010 (C#) and I want to prevent the end-user to move or edit all the shapes that I have programmatically created.
I have already sought in the framework but I think it's not allowed programmaticaly. Has anyone already encountered this kind of limitations and could help me to find a solution?
I know that some people create their add-in thanks to C++ because there are a lot of limitations in office.
I have found two solutions :
The first is to catch all events from the "commandBars.OnUpdate" like this great sample code : http://code.msdn.microsoft.com/CSExcelNewEventForShapes-0e26b1f2#content
Then you can impose the position/the color or everything you want to your shape.
The second one is more "brutal" > unselect immediately the shape. When you catch all the events from the "CommandBars.OnUpdate" do this :
To see which shape is selected :
var selectedShape = this.Application.ActiveWindow.Selection.ShapeRange[1]
In all my shapes, I have set a tag with an ID. I have just to check that there are an ID in the tags of the selectedShape and if this is the case :
this.Application.ActiveWindow.Selection.Unselect();
Then I show a messageBox to warn the user to do not select this kind of shape.
I don't like this solution but it's the only one that I have found and it works.
I believe this is not possible. A way of achieving this to a certain extent (people can work around it if they figure out how to select the shapes below) is by making a transparent rectangle the size of the canvas and binding a custom event to that (like you described in your comment). The transparent rectangle is overlaying the shapes you created so people can no longer access the shapes that way. Of course if they are capable of figuring out how to select the shapes they can move them anyway...
Alternatively, to make people not do stuff like that (you only stop the inexperienced) you can also set them up as master slides.
Only 'real' solution for people not doing that? Images .. but then they can move the image too!
Where can I get started drawing animated geometry in C#? I would like to draw a sort of countdown timer by drawing a partially shaded circle. At start the circle would be fully shaded, at 75% 3/4 of the circle would be shaded and at 0 completely unshaded. I really don't know where to begin with something like this.
If you still don't understand what I need, a lot of games use this sort of animation to represent a "cooldown" on an item or skill. Like a second hand going around a clock, revealing what is beneath it.
WPF is my target application but I imagine I will need to use some sort of GDI api.
You could start out with the drawing examples here, for how to make your pie-like graphic:
http://www.codeproject.com/KB/WPF/PieChartDataBinding.aspx
It looks like they use StreamGeometryContext, along with LineTo and ArcTo.
You could then work on applying an animation to the properties on that graphic, so the "slice" gets bigger over time, by changing the arc length:
http://msdn.microsoft.com/en-us/library/ms752312.aspx#applyanimationstoproperty
You could then wrap this all up nicely in a UserControl, with custom dependency properties, so you can reuse this throughout your app.
Edit: I was thinking you meant the shaded pie like in World of Warcraft. What you want is actually simpler. See can poyrazoğlu's answer for the graphical approach to take (although you really only need the top black circle, if you're going with an opacity approach).
Yes, it's really easy with WPF.
Just create another circle on top of the circle, make that one black, and let a timer update the opacity of the top circle from 1 to 0 by time (or whatever you want).
This is the "easy" way. A more "convenient", or "WPF-style" approach would include Bindings and possibly value conversions, you'll be binding the opacity of the circle to a custom value with a value converter (or decrementing that value, anyway there are lots of ways).
Choose whatever you want. They'll both work.
In a WPF standalone-application I need to draw an image based on a series of 'commands' such as "text a at position x,y" and "draw line from x1,y1 to x2,y2".
My problems and considerations are outlined below - any help and comments are most appreciated!
The image is of a water pump constructed by our company.
The commands are generated by a proprietory system within our company.
There are no problems interpreting the commands.
My issue is with
a) what WPF control should I choose to draw it 'on' ?
b) how can I move the major part of the code to unit-testable classes?
a1) I have tried with PathGeometry, which is excellent for drawing geometric shapes but can't draw text.
a2) I have tried with Shape, which supports drawing text, but is less advanced with respect to geometry.
a3) Could I use the strength in each of the two, and 'apply' a PathGeometry to a Shape?
a4) I need to handle MouseOver after the drawing to highlight based on the mouse position. It can be done through computing 'behind the scenes' the object nearest mouse position (though possible, it's heavy!) but can the choice of rendering Control help me out?
b1) I do not expect the end drawing to be subjectable to test?
b2) How 'deep' should I reference controls belonging in the GUI? Gut feeling says no deeper than ViewModel (not business level), but the higher I keep it, the more code remains in places where they can't be unit tested.
Here are answers specific to WPF:
You can draw on a Canvas, wich lets you set element's position (Canvas.SetLeft, Canvas.SetTop, ...)
And you can perfectly use PathGeometry, Shape, etc... you should also have a loop at GeometryGroup which allows to group all geometry as one.
For the text, if you want text as a Geometry, you can use FormattedText with the BuildGeometry method..
About unit testing.
WPF databinding is very good with binding data, such as string to text box. It is less good with user commands. It is even worse with telling UI to do things, such as "draw line" - you may be able to come up with some funky ItemPresenter bound to collection of shape view models, but I imagine it would be hard and will introduce too many unnecessary artifacts. Bottom line: MVVM is probably not for this project.
Instead, you may use the "passive view" approach. You define a control-agnostic "virtual machine" interface for your view. Something like
interface IView
{
void AddLine(int x1, int y1, int x2, int y2);
void DrawText(...);
}
Your view should have a straightforward implementation of this interface with minimum logic: each method is maximum 2-3 lines, no conditions or loops. This is a "dumb" passive view which is not testable.
The rest of the system (namely, Presenter) talks to the IView interface and knows nothing about WPF or controls. Well, it may use some simple WPF types such as Color or Rectangle for convenience.
You can use mock library (e.g. Rhino Mocks) to write tests that make sure your Presenter makes the right calls to your passive view. You create a "mock" view and pass it to the presenter.