WPF Xaml Islands - UWP Map Control pixelated polyline - wpf

I'm currently migrating a WPF app from .Net Framework to .Net Core (3.1). This application currently uses the MapControl from the Microsoft.Maps.MapControl.WPF assembly. The goal is to migrate this control to a UWP MapControl from the Microsoft.Toolkit.Wpf.UI.Controls assembly. One of the requirements, is the ability to draw Routes/Polylines on the map.
Following Microsoft's documentation (present in https://learn.microsoft.com/en-us/windows/uwp/maps-and-location/display-poi) I was able to draw lines on the map. However, the end result is not as desired (visually): the lines appear pixelated, as seen in the image bellow:
Current Result
How can I give a smooth look to this lines? Is there any way to apply anti-aliasing to them? After an extensive search online I was not able to find any function or property that allows for smooth rendering of this elements. What can I do to achieve this?
EDIT:
The .Net Framework way (using Microsoft.Maps.MapControl.WPF) of creating the MapPolyLine:
MapPolyline routeLine = new MapPolyline();
routeLine.Locations = myLocationCollection;
routeLine.Stroke = MY_COLOR;
routeLine.StrokeThickness = 5.0;
routeLine.StrokeLineJoin = PenLineJoin.Round;
The .Net Core way (using Microsoft.Toolkit.Wpf.UI.Controls) of creating the MapPolyLine:
var myPolyLine = new MapPolyline
{
Path = myPath,
FillColor = MY_COLOR,
StrokeColor = MY_STROKE_COLOR,
StrokeThickness = 6,
ZIndex = 1
};
myMap.MapElements.Add(myPolyLine);

Related

add zoom and scroll capability with code behind to SCICHART

Hi I want to add zoom and scroll with code behind to SCICHART
is this possible?
I tried xaml but It did not work. My manager wants it with code behind.
Yes this should be easy, for each modifier in SciChart WPF, you can add it in code behind like this:
var sciChartSurface = new SciChartSurface();
sciChartSurface.XAxis = new NumeriAxis();
sciChartSurface.YAxis = new NumeriAxis();
sciChartSurface.ChartModifiers.Add(new ZoomPanModifier());
sciChartSurface.ChartModifiers.Add(new MouseWheelZoomModifier());
sciChartSurface.ChartModifiers.Add(new ZoomExtentsModifier());
See a full list of the modifiers available in SciChart WPF here

Take a screenshot with silverlight 5 / xna

I'm trying to take a screenshot of a subclassed XNA DrawingSurface element from within a silverlight 5 application. This sl app will run inside an aspx page.
Here's what I've tried so far without success:
WriteableBitmap bmp = new WriteableBitmap(LayoutRoot, null);
testImage.Source = bmp;
with LayoutRoot being the parent control on the silverlight page and testImage is just an Image control on the page to see if the screenshot is correct.
This will render all the silverlight controls on the page just fine, but the drawingsurface part remains empty. In other words the XNA content is not rendered into the image.
I've also tried to render the XNA content to a RenderTarget2D, but the silverlight version of the render target does not seem to have any methods to save the data. I saw some WP7 examples that used a method called SaveAsJpeg(), but that doesn't seem to be available in the SL5 version of the class.
I would appreciate any help with this.
Greets,
Floris
One possibility would be to draw your screen into a RenderTarget2D and then use the method SaveAsPng like:
using (Stream stream = File.OpenWrite("filename.png"))
{
renderTarget2D.SaveAsPng(stream, renderTarget2D.Width, renderTarget2D.Height);
}

How do you find the screen position of a control in silverlight on WP7?

How do you find the screen position of a control in silverlight on WP7?
Any suggestions are much appreciated.
If you know how it's positioned (eg in a Canvas) there may be a more appropriate way to do things, but in general, you can use UIElement.TransformToVisual to convert between the control's and the global coordinate system:
var transform = myControl.TransformToVisual(Application.Current.RootVisual)
var offset = transform.Transform(new Point(0,0))
Be sure that the control has undergone layout before trying to do this, if you do it too early the error messages are generally unhelpful.
(MSDN suggests the method is present in WP7, I don't have the SDK installed to test)

Should I be using AdornerLayer to avoid clipping my adorner off-screen?

I'm writing some WPF code involving Adorners. I'm using Josh Smith's UIElementAdorner.cs (found in the project on his Infragistics Blog). I'm adorning with a blurb of information text. I need to place my adorner smartly, so that it does not clip off the screen.
What's the best way to find out if I'm going to clip?
I'm using the following code to create and place my adorner. I have a funny feeling that basing whether or not I'll clip on the AdornerLayer isn't the best option.
var infoBubble = new InfoBubble {InformationText = #"I like cheese."};
var adornedElementRect = new Rect(Target.DesiredSize);
var layer = AdornerLayer.GetAdornerLayer(Target);
var adorner = new UiElementAdorner<Control>(Target) { Child = infoBubble };
adorner.Measure(new Size(layer.ActualWidth, layer.ActualHeight));
var adornerRect = new Rect(adorner.DesiredSize);
var top = -1*(adornerRect.Height);
var left = adornedElementRect.Width/2;
// Using layer to judge where to place the adorner
var upperLeftPoint = Target.TranslatePoint(new Point(left, top), layer);
var lowerRightPoint = Target.TranslatePoint(new Point(left + adornerRect.Width,
top + adornerRect.Height), layer);
if (upperLeftPoint.Y < 0) top -= upperLeftPoint.Y; // shift down by Y
if (lowerRightPoint.X > layer.ActualWidth)
left -= (lowerRightPoint.X - layer.ActualWidth); // shift left
Keep in mind that this code is contained in a TargetedTriggerAction that designers (aka users of Blend) are expected to use when they want information blurbs above certain UI elements. Thus, this code will know very little about the element to be adorned or its environment.
Yes, is the best answer I can discern.
According to further reading and some experimentation, when calling GetAdornerLayer we receive the lowest layer above the target control in the visual tree. This means we could get a layer below the AdornerDecorator's layer defined in a Window's template. That lower AdornerDecorator could have ClipToBounds="True" (I have no idea why, but it could).
Knowing this information, I can be relatively certain that the AdorneLayer I'm drawing into is the best bounding box for whatever I'm drawing. I could have the ability to draw outside this box (for example if ClipToBounds were False on a AdornerDecorator lower than the Window's), but I shouldn't count on that ability.

Rotating a .NET panel in Windows Forms

We use Windows Forms and custom user controls, and I would like to be able to rotate the panel hosting the userControl in a particular form. I have seen similar functionnalities with WPF, but I can't use it for the moment. Is it possible to achieve the rotation of a panel and its children using possibly built-in .NET methods or GDI+?
I have seen some pretty cool visual effect with menus that are displayed in game development, so I was wondering if it would be possible to create similar effects using Windows Forms.
Rotating a panel and its children in Windows Forms is not something directly supported, and I think it will end up being a buggy headache that could easily suck up lots of time. It's especially painful to think about when you could do this in WPF with zero lines of C# code and only a tiny bit of XAML.
You can use rotations in GDI+ by calling the RotateTransform method on a Graphics object.
However, rotating an entire control is not so simple, and will depend heavily on how the control is implemented.
If it's a composite UserControl that has other controls inside of it, you're out of luck.
If it's a sinlge control that paints itself, try inheriting the control, overriding the OnPaint method, and calling RotateTransform on the Graphics object. However, you will probably have trouble with it. In particular, you will probably need to override all of the mouse events and call the base control's events with rotated coordinates.
You can get halfway there by calling the DrawToBitmap method on your panel, then rotating the bitmap and displaying it e.g. in a PictureBox:
var bitmap = new Bitmap(panel.Width, panel.Height);
panel.DrawToBitmap(bitmap, new Rectangle(Point.Empty, panel.Size));
bitmap.RotateFlip(RotateFlipType.Rotate270FlipNone);
var pictureBox = new PictureBox();
pictureBox.Location = panel.Location;
pictureBox.SizeMode = PictureBoxSizeMode.AutoSize;
pictureBox.Image = bitmap;
Controls.Remove(panel);
Controls.Add(pictureBox);
Rotation angles other than 90-degree increments are also possible, if you draw the bitmap into another bitmap using GDI:
var bitmap2 = new Bitmap(bmp.Width + 75, bmp.Height + 100);
var graphics = Graphics.FromImage(bmp2);
graphics.TranslateTransform(bitmap2.Width / 2, bitmap2.Height / 2);
graphics.RotateTransform(-15f);
graphics.TranslateTransform(-bitmap.Width / 2, -bitmap.Height / 2);
graphics.DrawImageUnscaled(bitmap, Point.Empty);
graphics.Dispose();
The problem of course is that you're only displaying an image of your panel, and not the panel itself, so it's no longer possible to interact with the controls inside.
That could probably be done as well, but you would have to mess with window messages, which gets quite a bit more complicated. Depending on your needs you might also be able to get away with handling click and key events on the PictureBox, manipulating the controls in the panel, and then updating the image.

Resources