I have an application with a Microsoft.Maps.MapControl.WPF map, and a few layers added with mapView.Children.Add(layer).
Each of those layers has different types of overlays on it, which are images added with layer.Children.AddChild(image, locationRect).
I want to be able to move, resize and rotate those objects from code (not from xaml which knows nothing about them), but I don't seem to be able to do the first two (rotation being quite simple).
After trial and error and finding some non Microsoft documentation I see that MapLayer.GetPositionRectangle(UIElement) returns the correct location of the object, so it would seem logical that MapLayer.SetPositionRectangle() should set it, but it doesn't and I can't find any examples of anything on the web that programatically moves an object to a new Lat/long.
Is there a way of moving a geographical object on the map, or do I have to either remove it and add it in the right place, or just move it on the canvas in X/Y coords that I have worked out from the lat/long, both of which seem wrong somehow, but this is my first WPF application (normally use forms) and maybe this is the way it is done?
The Windows-universal-samples that exist on Microsoft github page can help you. There is an example of MapControl where you can get some ideas.
This sample demonstrates how to use the universal map control (MapControl) in a UWP app.
MapControl Basics: adjusting the ZoomLevel, Heading, DesiredPtich, and map stype
Adding points of interest on the map: PushPins, images, and shapes
Adding XAML overlays on the map
Showing 3D locations in MapControl
Showing Streetside experience within MapControl
Launching Maps using URI Schemes
Url: https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/MapControl
After this example, if there is more question, post here to solve it.
I think, the best way is getting an model for this XAML, where you can update this properties.
What you can do is apply standard transitions to your image through code. you can use the MapLayer.SetPosition to link it to a location on the map. You may want to use an position origin/offset or a margin to align a specific point of the image with the location.
https://msdn.microsoft.com/en-us/library/microsoft.maps.mapcontrol.wpf.maplayer.setposition.aspx
https://msdn.microsoft.com/en-us/library/microsoft.maps.mapcontrol.wpf.maplayer.setpositionorigin.aspx
https://msdn.microsoft.com/en-us/library/microsoft.maps.mapcontrol.wpf.positionorigin.aspx
https://msdn.microsoft.com/en-us/library/microsoft.maps.mapcontrol.wpf.maplayer.setpositionoffset.aspx
Related
I am trying to make a UI prototype for a bus route design app. The intended behaviour is to let the user paint with a brush over the streets, but not over buildings. The idea is to get something like you see in the image below where the pink line represents the route that the user just painted.
I am currently using a basic InkCanvas and InkToolbar in order to do this.
My problem is that I have no idea on how to prevent users from painting over buildings. I tried to create several InkCanvas, each one of them representing a unique street, but that's a very clunky solution. Should I stick to this "solution" or is there any other thing that allows me to prevent the user from painting?
UWP-xaml InkCanvas: Is there a way to deny painting on specific zones?
Great question, for your requirement, the better way is that draw line in MapControl with MapPolyline.
If you want to draw the line with ink-canvas, You need to declare that the building is not available. and please check official code sample scenario 8. When the stroke
cross the circle, it will be removed.
(Before this gets marked as a duplicate, I'd like to say that I've tried the answers on other posts, but they don't seem to work for my specific issue.)
I'm creating a sort of "map game", where there's a map split into multiple areas. Currently, this is what I have:
It works, but it's not pretty. I want to make the buttons (currently they're the Rectangle control, but I can change that easily) the right shape.
I tried making a path in Inkscape, which gave me this SVG path:
m 283.60033,267.22114 11.61675,32.57742 14.14214,-8.33376 10.35406,-1.01015 11.61676,-5.3033 10.6066,-5.05077 0,-16.66751 -34.85027,-3.78808 -8.08122,2.77792 -14.64721,0.75762 z
However, when I tried to make a Button (and later Polygon) use the path, it didn't work and instead made a completely different shape.
The Buttons need to have a background color that can change during runtime, so a PictureBox won't work.
Is there a reason why the Path didn't work? Or maybe there is a much easier method?
EDIT: Here is the code I used for the Polygon
<Polygon Fill="Blue" Points="283.60033,267.22114 11.61675,32.57742 14.14214,-8.33376 10.35406,-1.01015 11.61676,-5.3033 10.6066,-5.05077 0,-16.66751 -34.85027,-3.78808 -8.08122,2.77792 -14.64721,0.75762" Margin="248,102,956,22" RenderTransformOrigin="0.5,0.5" Grid.ColumnSpan="2"/>
And here is the result, which is the same shape I got when I tried changing the shape of a Button (unfortunately I deleted the code for that):
Here is what it should look like (path drawn in Inkscape):
I figured it out and it was actually pretty easy! I actually didn't need Inkscape at all.
I imported the map image into Blend, and I traced the area with the Pen tool and made it into a Path, which I copied back into Visual Studio.
Example:
Are you sure you didn't get mixed up with which part you picked out the xaml inkscape produced?
Because that's roughly the top right part of the iberian peninsular. Like your drawn map. Roughly anyhow. That's just a polygon - with hard edges. Meaning however you produced it, you didn't trace the curvy/rough edges of what you're showing us.
Also.
If you look at the data that's in it.
See where it starts?
m 283.60033,267.22114
Those are x,y co-ordinates.
268px left, 267px down
From the top left corner of whatever container you put it in.
Is that going to work for you?
I'm working on a LineGraph control which consists many DependencyProperties that affect how the control should display its data. For example, the control contains the following properties to affect its axes:
AxisStroke - Color of the axes.
AxisThickness - Stroke thickness of the axes.
It also contains properties for display numbers & tick marks
VerticalTicks - True/False to indicate whether or not ticks appear along the vertical axis
HorizontalTicks - True/False to indicate whether or not ticks appear along the horizontal axis
VerticalMin - Minimum value on the vertical axis (numeric)
VerticalStep - The distance in between each vertical tick
VerticalMax - Maximum value on the vertical axis (numeric)
HorizontalMin - Minimum value on the horizontal axis (numeric)
HorizontalStep - The distance in between each horizontal tick
HorizontalMax - Maximum value on the horizontal axis (numeric)
And many more properties exist to allow for different line styles on a single graph (LineColor, LineThickness, DataPointShape, and DataPointIcon to name a few).
My goal is to be able to call out my LineGraph in XAML to insert it into a Window. I would like to be able to specify each of these settings inside the XAML as well, and see the new rendered image of the control in the WPF designer.
Now, given there is a lot of geometric shapes to render on the LineGraph, I though using a Canvas would be a good choice to render the data. Unfortunately, when I'm working in XAML, I cannot perform computations for the locations of shapes based on the control's width & height.
And yes, the shapes' locations must be computed because the data points for the graph are dynamic and the tick-related information is dynamic. Not to mention, I would like to display the actual values along each axis of the LineGraph.
So, I thought I might be able to display this control as if I was doing the rendering in C# code. Other windowing frameworks sometimes provide a Render method that can be used for laying out all of the sub-components.
Doing this, however, doesn't seem possible since WPF relies heavily on XAML for the visual appearance of controls. Also, requiring that the WPF designer must display the LineGraph based on the properties and data specified, it doesn't seem like C# code would solve the problem.
I suppose my questions are these:
How can I render data dynamically inside of a WPF control?
Am I able to specify in C# how my control is rendered, allowing the WPF designer to reflect it?
Side Note:
I've done quite a bit of research, but I am only finding information on how to implement more simple types of controls. If you know of any references that contain information on this topic, please feel free to post them in addition to your answers. I will be more than happy to learn how to do this completely.
EDIT:
I've created a graph using Excel to elaborate what the LineGraph control might look like if it has correct data and properties.
I will answer this based on my experience on implementing custom built graphing libraries in WIN32, WinForm, WPF, WinCE, WP8+WinRT, ....and even on a FPGA :)
It's extremely difficult to implement one from scratch. It may seem easy at first but you will run into a lot of "What should I do if this happens?". For example, in your above graph it seems you got a DataPoint # (5,100) it graphs it pretty well. But lets say, I add another DataPoint # (5.000000005, 0). How would you handle that in your code? Would you say that each pixel on the graph represents an exact value on the X-Axis, or does each pixel represent a range of X-Values?
I would recommend that you use an already establish library to do what you want to do unless you need something very specific like lets say you need horizontal cursors on the graph (think Tektronix Oscilloscope) and you need to calculate some values in between the two cursors.. then maybe you need to implement your own custom one or build on top of an open source one.
So, if you are still adamant of creating your own custom control here are answers to your questions.
How can I render data dynamically inside of a WPF control?
You can use a WriteableBitmap and create your own primitive drawing library from that. After you're done rendering, set it as the ImageSource of your control.
Or you can use WriteableBitmapEx which has GDI like drawing functions already implemented for you.
WriteableBitmapEx CodePlex Page, I also think you can just get it from NuGet as well.
You can also use a <Canvas> and add UI elements to that as well.
Am I able to specify in C# how my control is rendered, allowing the WPF designer to reflect it?
This depends on how you create your controls, but yes you can create Properties in your custom control that will appear in the Designer. Allowing you to change it thus updating the display. I would read a lot of tutorials about writing your own custom user control library. They can explain it better than I can in a SO answer. If you implement the properties correctly it should like so.....
Full Size Image: http://i.stack.imgur.com/pmevo.png
After changing the Number of Rows from 15 to 10 and the starting Y offset to -1 (thus moving the graph up and making the rows a lot taller)
Full Size Image: http://i.stack.imgur.com/0RKnA.png
In my metro app using XAML and C# I need to plot some Pins on the Map control. I found several samples which all of them having plot the pins in the code behind file(add pin as children to the map control). Is it possible in another way? (similar to Windows Phone)
You can create a custom control that derives from ItemsControl. It will monitor changes to a backing ObservableCollection in your ViewModel. Then, you can just add/subtract pins from that.
Note: This is not necessarily a simple task. There is a reason there are companies creating complex controls for profit, and this is certainly a more complex one. It's not nearly impossible, but it will take some work to accomplish, much less successfully.
To get you started, it will most likely need:
Some kind of backing Map image
The ability to convert coordinates in the Pin to (x,y) pixel coordinates on the map image
You'll most likely need to override:
MeasureOverride : Find out how much space the map needs
ArrangeOverride : Find out where all of the current children go
OnDisconnectVisualChildren : What to do when you remove a pin
PrepareContainerForItemOverride : Creating an item container for items added/removed
You can then go on to add things like childtransitions (so they 'pop in').
Then, all you need to do is set up your VM, load your pins, and you're off to the races.
Good coding!
When I place a byte tag on my Surface table the tag is recognized by tag visualizer as it should, and shows a tag visualization (just a black circle) beneath the tagged object.
Underneath my tag visualization is a WPF Bing map control.
Here is the problem: The map is treating the recognized tag as a touch point. For TouchFrameEventArgs e produced when the tag is placed on the screen:
e.GetTouchPoints(myMap)
Count = 1
[0]: {Microsoft.Surface.Presentation.Input.SurfaceTouchPoint}
The map control gets a touch point even though the TouchDevice for this touchPoint is captured by the TagVisualizer and NOT the map:
_touchPoint.TouchDevice.Captured.ToString()
"Microsoft.Surface.Presentation.Controls.TagVisualizer"
Why does this happen? That is, why does the map control get a touch point after the TagVisualizer has captured the tag?
This is a problem because when a tag is on the table, the map cannot be panned and zoomed normally with other touches...because it is treating the tag as another finger! I would like to make this stop!
The tag visualizer is across the entire screen, thus the entire app is a child element of the visualizer.
I am working on a program for a device made for Surface, an actual MS Surface Table (Samsung SUR40), and developing my program on a normal touchscreen monitor not designed for surface (testing on it using the input simulator). Interestingly this problem occurs on the actual Surface table, but the symptoms are different on the monitor not made for Surface (i.e. using Input Simulator).
I have tried:
this.myMap.ReleaseTouchCapture(_touchPoint.TouchDevice);
...after recognizing the touch event of the tag itself, but this does not do anything since the touch has not been actually captured by the map control.
Can anyone help with this? Does anyone know how the Bing Maps WPF control uses touch events? Or how the TagVisualizer treats tags as touches?
Many Thanks!
After some more troubleshooting on this, it appears that the touch events coming from the tag were actually from the physical object outside the tag area. I covered the object with IR-absorbing black (to make it invisible to the IR camera) and that eliminated the touch events. Problem solved!
It turns out that the TagVisualizer does not send a touch event when a tag is recognized.