I have 5 Images and a border, when the user clicks an image, I want the border to slide over until it is directly over the Image that was clicked.
I am having a hard time figuring out this transform stuff. I am good with C# but new to wpf. I am quite certain that the translatetransform is what I need, but I have no idea how to implement it. Can someone show me, or point me to a good tutorial on this topic.
var RT=new TranslateTransform(90,0);
SelectBorder.RenderTransform = RT;
SelectBorder.BeginAnimation(...//I don't know what a dependency object is
I would recommend reading the documentation, it has a full example of how to use the method. (Also you would start the animation on the transform not the Border)
Related
I'm trying to make something similar to paint. I'm trying to figure out how make different brush styles. Like in Paint 3D you get a certain line fills when using the pen tool vs using the paint brush tool.
I have no idea where to even start. I've spent a good portion of the day looking through documentations, and watching YouTube videos. I'm more lost than when I started. The closest thing I came across was line caps, but that's definitely not what I'm looking for.
!!See the UPDATE below!!
Hans' link should point you in the right direction, namely toward TextureBrushes.
To help you further here a few points to observe:
TextureBrush is a brush, not a pen. So you can't follow a path, like the mouse movements to draw along that curve. Instead, you need to find an area to fill with the brush.
This also implies that you need to decide how and when to trigger the drawing; basic options are by time and/or by distance. Usually, the user can set parameters for these often called 'flow' and 'distance'..
Instead of filling a simple shape and drawing many of those, you can keep adding the shapes to a GraphicsPath and fill that path.
To create a TextureBrush you need a pattern file that has transparency. You can either make some or download them from the web where loads of them are around, many for free.
Most are in the Photoshop Brush format 'abr'; if they are not too recent (<=CS5) you can use abrMate to convert them to png files.
You can load a set of brushes to an ImageList, set up for large enough size (max 256x256) and 32bpp to allow alpha.
Most patterns are black with alpha, so if you want color you need to create a colored version of the current brush image (maybe using a ColorMatrix).
You may also want to change its transparency (best also with the ColorMatrix).
And you will want to change the size to the current brush size.
Update
After doing a few tests I have to retract the original assumption that a TextureBrush is a suitable tool for drawing with textured tips.
It is OK for filling areas, but for drawing free-hand style it will not work properly. There are several reasons..:
one is that the TextureBrush will always tile the pattern in some way, flipped or not and this will always look like you are revealing one big underlying pattern instead of piling paint with several strokes.
Another is that finding the area to fill is rather problematic.
Also, tips may or may not be square but unless you fill with a rectangle there will be gaps.
See here for an example of what you don't want at work.
The solution is really simple and much of the above still applies:
What you do is pretty much regular drawing but in the end, you do a DrawImage with the prepared 'brush' pattern.
Regular drawing involves:
A List<List<Point>> curves that hold all the finished mouse paths
A List<Point> curentCurve for the current path
In the Paint event you draw all the curves and, if it has any points, also the current path.
For drawing with a pattern, it is necessary to also know when to draw which pattern version.
If we make sure not to leak them we can cache the brush patterns..:
Bitmap brushPattern = null;
List<Tuple<Bitmap,List<Point>>> curves = new List<Tuple<Bitmap,List<Point>>>();
Tuple<Bitmap, List<Point>> curCurve = null;
This is a simple/simplistic caching method. For better efficiency you could use a Dictionary<string, Bitmap> with a naming scheme that produces a string from the pattern index, size, color, alpha and maybe a rotation angle; this way each pattern would be stored only once.
Here is an example at work:
A few notes:
In the MouseDown we create a new current curve:
curCurve = new Tuple<Bitmap, List<Point>>(brushPattern, new List<Point>());
curCurve.Item2.Add(e.Location);
In the MouseUp I add the current curve to the curves list:
curves.Add(new Tuple<Bitmap, List<Point>>(curCurve.Item1, curCurve.Item2.ToList()));
Since we want to clear the current curve, we need to copy its points list; this is achieved by the ToList() call!
In the MouseMove we simply add a new point to it:
if (e.Button == MouseButtons.Left)
{
curCurve.Item2.Add(e.Location);
panel1.Invalidate();
}
The Paint goes over all curves including the current one:
for (int c = 0; c < curves.Count; c++)
{
e.Graphics.TranslateTransform(-curves[c].Item1.Width / 2, -curves[c].Item1.Height / 2);
foreach (var p in curves[c].Item2)
e.Graphics.DrawImage(curves[c].Item1, p);
e.Graphics.ResetTransform();
}
if (curCurve != null && curCurve.Item2.Count > 0)
{
e.Graphics.TranslateTransform(-curCurve.Item1.Width / 2, -curCurve.Item1.Height / 2);
foreach (var p in curCurve.Item2)
e.Graphics.DrawImage(curCurve.Item1, p);
e.Graphics.ResetTransform();
}
It makes sure the patterns are drawn centered.
The ListView is set to SmallIcons and its SmallImageList points to a smaller copy of the original ImageList.
It is important to make the Panel Doublebuffered! to avoid flicker!
Update: Instead of a Panel, which is a Container control and not really meant to draw onto you can use a Picturebox or a Label (with Autosize=false); both have the DoubleBuffered property turned on out of the box and support drawing better than Panels do.
Btw: The above quick and dirty example has only 200 (uncommented) lines. Adding brush rotation, preview, a stepping distance, a save button and implementing the brushes cache takes it to 300 lines.
(Sorry if this is in the wrong place. I have been bouncing around SO and Programmers SE Sites all day and I keep getting flagged. Some insight as to what I am doing wrong would be helpful). Now on to my question:
I have been following the 3D WPF C# tutorial here: http://kindohm.com/technical/WPF3DTutorial.htm all the way up to the cube demo. I am wondering if there is a way to place text on the cube either as part of the texture or as 3D text attached to the cube. If someone could point me towards a tutorial or a code snippet that would be helpful. Thanks!
Update: I forgot to mention that the one thing that I am doing differently from the tutorial is that I am embedding the WPF ViewPort control inside of a WPF UserControl inside of an ElementHost inside of a Windows Form.
The tutorial shows how to use Material, with a SolidColorBrush. Besides SolidColorBrush there are some more kinds of Brushes can be used with the Material. For example You can use VisualBrush, in which you can use any kind of Visual, including DrawingVisual and even UIElement.
Notice that if you're going to render heavy scene with a lot of texts you might encounter performance issues. UIElement performs very bad in 3D scene, so I would prefer using DrawingVisual instead. If that's still not good enough, you can rasterize your DrawingVisual using RenderTargetBitmap and then use ImageBrush instead of the VisualBrush (that's good only if the text is static - if you would like to use animations you must use the VisualBrush without rasterization).
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);
So im developing this app, where i got something that reminds alot about a list, but it doesn't use a list control or something. I add grids & rectangels to a scrollviewer, and when i doubletap a grip or a rectangel, it dissapears with a fade animation (which i also need help to do, as well as fade in, fast, one by one on app startup), and when that happens, i want the grid or rectangel beneath the one that faded out (or was removed, what is the best solution?), to be slided up, and replace the empty position. Please, do not misunderstand the question, i dont want you to make it for me, i want to know how since i absolutely cannot find ANY solution at all. It kind of works like google now for android and iphone. How can i do this the best way? Thank you SO much! Best regards, Erik
My DoubleAnimation to fade the grid:
DoubleAnimation fadeGrid = new DoubleAnimation();
fadeGrid.From = 0;
fadeGrid.To = 1;
fadeGrid.Duration = new Duration(TimeSpan.FromSeconds(0.5));
fadeGrid.AutoReverse = false;
1) Use animations for your fade out and slide up. For fade, you'll be doing a DoubleAnimation on the Opacity property. For sliding items up, you'll be doing an animiation on the TranslateTransform property. See these MSDN guides: http://msdn.microsoft.com/en-us/library/windowsphone/develop/jj206955(v=vs.105).aspx and http://msdn.microsoft.com/en-us/library/windowsphone/develop/system.windows.media.translatetransform(v=vs.105).aspx
2) For actually properly moving things up, you'll want to capture the Completed event from the animiation (http://msdn.microsoft.com/en-us/library/windowsphone/develop/system.windows.media.animation.timeline.completed(v=vs.105).aspx). When the animiation completes, remove those controls from the StackPanel inside the ScrollViewer, and undo any position animation you did on the items below it to animate them 'sliding' up.
3) After creating an animiation, you need to add it to a storyboard:
Storyboard sb = new Storyboard();
sb.Children.Add(fadeGrid);
Storyboard.SetTarget(fadeGrid, myRectangle);
Storyboard.SetTargetProperty(fadeGrid, new PropertyPath("(UIElement.Opacity)"));
sb.Begin();
The syntax for the propertypath but not be quite perfect, but you get the idea. You can see another example that specifically mentions opacity here: http://blogs.msdn.com/b/silverlight_sdk/archive/2008/03/21/silverlight-animations-a-walkthrough.aspx
How would I draw something on a Canvas in C# for Windows Phone?
Okay, let me be a little more clear.
Say the user taps his finger down at 386,43 on the canvas. (the canvas is 768 by 480)
I would like my application to be able to respond by placing a red dot at 386,43 on the canvas.
I have no prior experience with Canvas whatsoever.
If this is too complex to be answered in one question (which it probably is), please give me links to other websites with Canvas and Drawing articles.
There are various ways of doing this. Depending on the nature of the red dot, you could make it a UserControl. For a basic circle, you can simply handle your canvas' ManipulationStarted event.
private void myCanvas_ManipulationStarted(object sender, ManipulationStartedEventArgs e)
{
Ellipse el = new Ellipse();
el.Width = 10;
el.Height = 10;
el.Fill = new SolidColorBrush(Colors.Red);
Canvas.SetLeft(el, e.ManipulationOrigin.X);
Canvas.SetTop(el, e.ManipulationOrigin.Y);
myCanvas.Children.Add(el);
}
I think you need to approach the problem differently. (I'm not including code on purpose, because of that).
Forms and controls in an Windows applications (including Phone) can be refreshed for several reasons, at any time. If you draw on a canvas in response to a touch action, you have an updated canvas until the next refresh. If a refresh occurs the canvas repaints itself, you end up with a blank canvas.
I have no idea what your end goal is, but you likely want to either keep track of what the user has done and store that state somewhere and show it in a canvas on the repaint of the canvas. This could be done with storing all the actions and "replaying" them on the canvas, or simply storing the view of the canvas as a bitmap and reload the canvas with that bitmap when refreshed. But, in the later case I think using a canvas isn't the right solution.