Is there a Geopoint class available for Winforms (or an Analogue thereof)? - winforms

In my UWP app, I use a Geopoint class:
using Windows.Devices.Geolocation;
. . .
List<Geopoint> locations;
In a Winforms app, this is not available - Geopoint is not recognized. Is there an analogous class available for Winforms apps?
The same is true for the BasicGeoposition object - not recognized.
UPDATE
I want the GeoPoint and BasicGeoposition classes so I can do things like this:
BasicGeoposition location = new BasicGeoposition();
location.Latitude = 36.59894360222391; // Monterey == 36.6002° N
location.Longitude = -121.8616426604813; // Monterey == 121.8947° W (West is negative)
Geopoint geop = new Geopoint(location);
await map.TrySetSceneAsync(MapScene.CreateFromLocation(geop));
cmbxZoomLevels.SelectedIndex = Convert.ToInt32(map.ZoomLevel - 1);
map.Style = MapStyle.Aerial3DWithRoads;
UPDATE 2
I tried the code provided in the answer:
this.UserControl1.myMap.AnimationLevel = AnimationLevel.Full;
this.userControl11.myMap.Loaded += MyMap_Loaded;
...but it won't compile. I don't have a UserControl11 (which is what the answer's code has), but I do have a UserControl1, yet it is not recognized:
This is the XAML in question (Bing Maps key obfuscated):
<UserControl x:Class="MyMaps.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:m="clr-namespace:Microsoft.Maps.MapControl.WPF;assembly=Microsoft.Maps.MapControl.WPF">
<Grid>
<m:Map CredentialsProvider="Gr8GooglyMoogly" x:Name="myMap" />
</Grid>
</UserControl>

To set the view of the Bing Maps WPF control, you can use SetView method. The method have different overloads, for example you can pass a Location(which you create based on the latitude and longitude of your desired location) and a zoom-level to the method like this:
var location = new Location(47.604, -122.329);
this.userControl11.myMap.SetView(location, 12);
Same can be achieved by setting Center and ZoomLevel.
Download or Clone the example
You can download or close the working example from here:
Clone r-aghaei/WinFormsWpfBingMaps
Download master.zip
Step by Step Example - Zoom into Seattle as initial view
Follow instructions in this post to create a Windows Forms project which uses WPF Bing Maps Control.
Handle the Load event of the Form and use the following code:
private void Form1_Load(object sender, EventArgs e)
{
this.userControl11.myMap.AnimationLevel = AnimationLevel.Full;
this.userControl11.myMap.Loaded += MyMap_Loaded;
}
private void MyMap_Loaded(object sender, System.Windows.RoutedEventArgs e)
{
var location = new Location(47.604, -122.329);
this.userControl11.myMap.SetView(location, 12);
}
Make sure you use using Microsoft.Maps.MapControl.WPF;.
As a result, the map zooms in Seattle as center location:
More information:
You may want to take a look at the following links for more information:
How can I add a Bing Maps Component to my C# Winforms app?
Bing Maps WPF Control
Developing with the Bing Maps WPF Control
Bing Maps WPF Control API Reference

For those who are looking to use Windows Community Toolkit Map Control which is different from Bing Maps WPF Control, you can follow these steps to use Windows Community Toolkit Map Control for Windows Forms.
Note: Windows 10 (introduced v10.0.17709.0) is a prerequisite.
Create a Windows Forms Application (.NET Framework >=4.6.2 - I tried myself with 4.7.2)
Install Microsoft.Toolkit.Forms.UI.Controls NuGet package.
Add an app.manifest file: Right-click on project → Add New Item → Choose Application Manifest File (Windows Only) which is located under General node.
Open the app.manifest file and uncomment the supportedOS under <!-- Windows 10 -->:
<!-- Windows 10 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
Handle the Load event of your form and add the following code:
private void Form1_Load(object sender, EventArgs e)
{
var map = new MapControl();
map.Dock = DockStyle.Fill;
map.MapServiceToken = "YOUR KEY";
map.LoadingStatusChanged += async (obj, args) =>
{
if (map.LoadingStatus == MapLoadingStatus.Loaded)
{
var cityPosition = new BasicGeoposition() {
Latitude = 47.604, Longitude = -122.329 };
var cityCenter = new Geopoint(cityPosition);
await map.TrySetViewAsync(cityCenter, 12);
}
};
this.Controls.Add(map);
}
Also make sure you include required usings:
using Microsoft.Toolkit.Forms.UI.Controls;
using Microsoft.Toolkit.Win32.UI.Controls.Interop.WinRT;
Note 1: I was unable to add the control in designer because of an exception on design-time when I tried to drop the control on form, so I decided to use add it at run-time.
Note 2: You need to Get a Key to use map; however for test purpose you may ignore getting the key.
Run your application and see the result:
More information
MapControl for Windows Forms and WPF
Source code: Microsoft.Toolkit.Forms.UI.Controls.MapControl
WinForms control is a wrapper around WPF Windows.UI.Xaml.Controls.Maps.MapControl
Display maps with 2D, 3D, and Streetside views

Related

WPF native windows 10 toasts

Using .NET WPF and Windows 10, is there a way to push a local toast notification onto the action center using c#? I've only seen people making custom dialogs for that but there must be a way to do it through the os.
You can use a NotifyIcon from System.Windows.Forms namespace like this:
class Test
{
private readonly NotifyIcon _notifyIcon;
public Test()
{
_notifyIcon = new NotifyIcon();
// Extracts your app's icon and uses it as notify icon
_notifyIcon.Icon = Icon.ExtractAssociatedIcon(Assembly.GetExecutingAssembly().Location);
// Hides the icon when the notification is closed
_notifyIcon.BalloonTipClosed += (s, e) => _notifyIcon.Visible = false;
}
public void ShowNotification()
{
_notifyIcon.Visible = true;
// Shows a notification with specified message and title
_notifyIcon.ShowBalloonTip(3000, "Title", "Message", ToolTipIcon.Info);
}
}
This should work since .NET Framework 1.1. Refer to this MSDN page for parameters of ShowBalloonTip.
As I found out, the first parameter of ShowBalloonTip (in my example that would be 3000 milliseconds) is generously ignored. Comments are appreciated ;)
I know this is an old post but I thought this might help someone that stumbles on this as I did when attempting to get Toast Notifications to work on Win 10.
This seems to be good outline to follow -
Send a local toast notification from desktop C# apps
I used that link along with this great blog post- Pop a Toast Notification in WPF using Win 10 APIs
to get my WPF app working on Win10. This is a much better solution vs the "old school" notify icon because you can add buttons to complete specific actions within your toasts even after the notification has entered the action center.
Note- the first link mentions "If you are using WiX" but it's really a requirement. You must create and install your Wix setup project before you Toasts will work. As the appUserModelId for your app needs to be registered first. The second link does not mention this unless you read my comments within it.
TIP- Once your app is installed you can verify the AppUserModelId by running this command on the run line shell:appsfolder . Make sure you are in the details view, next click View , Choose Details and ensure AppUserModeId is checked. Compare your AppUserModelId against other installed apps.
Here's a snipit of code that I used. One thing two note here, I did not install the "Notifications library" mentioned in step 7 of the first link because I prefer to use the raw XML.
private const String APP_ID = "YourCompanyName.YourAppName";
public static void CreateToast()
{
XmlDocument toastXml = ToastNotificationManager.GetTemplateContent(
ToastTemplateType.ToastImageAndText02);
// Fill in the text elements
XmlNodeList stringElements = toastXml.GetElementsByTagName("text");
stringElements[0].AppendChild(toastXml.CreateTextNode("This is my title!!!!!!!!!!"));
stringElements[1].AppendChild(toastXml.CreateTextNode("This is my message!!!!!!!!!!!!"));
// Specify the absolute path to an image
string filePath = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86) + #"\Your Path To File\Your Image Name.png";
XmlNodeList imageElements = toastXml.GetElementsByTagName("image");
imageElements[0].Attributes.GetNamedItem("src").NodeValue = filePath;
// Change default audio if desired - ref - https://learn.microsoft.com/en-us/uwp/schemas/tiles/toastschema/element-audio
XmlElement audio = toastXml.CreateElement("audio");
//audio.SetAttribute("src", "ms-winsoundevent:Notification.Reminder");
//audio.SetAttribute("src", "ms-winsoundevent:Notification.IM");
//audio.SetAttribute("src", "ms-winsoundevent:Notification.Mail"); // sounds like default
//audio.SetAttribute("src", "ms-winsoundevent:Notification.Looping.Call7");
audio.SetAttribute("src", "ms-winsoundevent:Notification.Looping.Call2");
//audio.SetAttribute("loop", "false");
// Add the audio element
toastXml.DocumentElement.AppendChild(audio);
XmlElement actions = toastXml.CreateElement("actions");
toastXml.DocumentElement.AppendChild(actions);
// Create a simple button to display on the toast
XmlElement action = toastXml.CreateElement("action");
actions.AppendChild(action);
action.SetAttribute("content", "Show details");
action.SetAttribute("arguments", "viewdetails");
// Create the toast
ToastNotification toast = new ToastNotification(toastXml);
// Show the toast. Be sure to specify the AppUserModelId
// on your application's shortcut!
ToastNotificationManager.CreateToastNotifier(APP_ID).Show(toast);
}
UPDATE
This seems to be working fine on windows 10
https://msdn.microsoft.com/library/windows/apps/windows.ui.notifications.toastnotificationmanager.aspx
you will need to add these nugets
Install-Package WindowsAPICodePack-Core
Install-Package WindowsAPICodePack-Shell
Add reference to:
C:\Program Files (x86)\Windows Kits\8.1\References\CommonConfiguration\Neutral\Windows.winmd
And
C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETCore\v4.5\System.Runtime.WindowsRuntime.dll
And use the following code:
XmlDocument toastXml = ToastNotificationManager.GetTemplateContent(ToastTemplateType.ToastImageAndText04);
// Fill in the text elements
XmlNodeList stringElements = toastXml.GetElementsByTagName("text");
for (int i = 0; i < stringElements.Length; i++)
{
stringElements[i].AppendChild(toastXml.CreateTextNode("Line " + i));
}
// Specify the absolute path to an image
string imagePath = "file:///" + Path.GetFullPath("toastImageAndText.png");
XmlNodeList imageElements = toastXml.GetElementsByTagName("image");
ToastNotification toast = new ToastNotification(toastXml);
ToastNotificationManager.CreateToastNotifier("Toast Sample").Show(toast);
The original code can be found here: https://www.michaelcrump.net/pop-toast-notification-in-wpf/
I managed to gain access to the working API for windows 8 and 10 by referencing
Windows.winmd:
C:\Program Files (x86)\Windows Kits\8.0\References\CommonConfiguration\Neutral
This exposes Windows.UI.Notifications.
You can have a look at this post for creating a COM server that is needed in order to have notifications persisted in the AC with Win32 apps https://blogs.msdn.microsoft.com/tiles_and_toasts/2015/10/16/quickstart-handling-toast-activations-from-win32-apps-in-windows-10/.
A working sample can be found at https://github.com/WindowsNotifications/desktop-toasts

Dynamically adding a web user control to a web user control (asp.net vb)

I need to convert a C# web site to VB. There is a page that loads a custom web control (WholeLife.ascx) and then within this control, could possibly load multiple web user controls dynamically (WholeLifeChild.ascx).
The C# version works, the VB version just cannot seem to recognize the controls (WholeLifeChild.ascx) that it neess to load within the main control (WholeLife.ascx).
C# Version (works):
private WholeLifeChild _selectedChild;
// Later, looping with a foreach creates loads multiple childChoice:
WholeLifeChilds childChoice = (WholeLifeChilds)LoadControl("~/Controls/WholeLifeChild.ascx");
phChildChoices.Controls.Add(childChoice);
childChoice.ID = "ChildChoices-" + appRate.DependentID;
childChoice.Initialize(appRate, _WholeLifeCoverage);
childChoice.ChildChoicesChanged += new WholeLifeChild.ChangingHandler(ChildChoices_Changed);
VB Version (cannot find custom web user control):
Private _selectedChild As WholeLifeChild **(vb complains here on WholeLifeChild)**
'Later, looping with a foreach creates loads multiple childChoice:
(VB complains on the WholeLifeChild as if it cannot locate it)
Dim childChoice As WholeLifeChild = DirectCast(LoadControl("~/UserControls/WholeLifeChild.ascx"), WholeLifeChild)
phChildChoices.Controls.Add(childChoice)
childChoice.ID = "ChildChoices-" + appRate.DependentID
childChoice.Initialize(appRate, _WholeLifeCoverage)
childChoice.ChildChoicesChanged += New WholeLifeChild.ChangingHandler(AddressOf ChildChoices_Changed)
'This VB Version cannot find the WholeLifeChild.ascx control which is in the same directory as the control it's loading to (WholeLife.ascx).
Any help would be greatly appreciated.

WP7 Bing Maps 'Invalid Credentials' Error

I'm trying to use a bing maps control on a windows phone 7 silverlight application and it shows this error overlaid on the map.
Invalid Credentials, Sign up for a
Developer Account
I've tried using app IDs from these two sites: http://www.bing.com/developers, and https://www.bingmapsportal.com/
am I doing something wrong? is there some account setting that I'm missing? For reference, here's how I'm defining the control and interacting with it:
<my:Map x:Name="MyMap" CredentialsProvider="<<myAppId>>" />
And in the code behind:
var vm = this.DataContext as ItemViewModel;
Pushpin pushpin = new Pushpin();
Location location = new Location()
{
Latitude = vm.Latitude,
Longitude = vm.Longitude
};
pushpin.Location = location;
MyMap.ZoomLevel = 15;
MyMap.Center = location;
MyMap.Children.Add(pushpin);
Go to http://bingmapsportal.com and sign in with your Windows Live ID. Once signed in, click Create or view keys in the menu on the left. If you haven't already, create an application by entering the name, URL, and selecting a type (Mobile). Once you've got your application created, copy the long string of characters and paste it into your XAML as the value of the CredentialsProvider attribute.
<my:Map CredentialsProvider="NOTREALVF7QTW-LZfG0p7-RhSPeGvlfx3fdtgR-Gk_SB-wfF8kCj2J7nI57wjIna" />
After much travail, I finally discovered that this occurs (at least on desktop SL; not sure about WP7) when the Thread.CurrentUICulture is set to the invariant culture. Be sure it is set to a specific culture (consider also setting Thread.CurrentCulture) in the App.Startup event handler, e.g.
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en-US");
You do still need AppID set, of course.

What is the simplest way to display (and change) an image resource on a WPF dialog (using C++/CLI)?

I have a C++/CLI GUI application and I want to display an image as a visual aid for the user to see what step in a procedure they're at. This image will need to be changed each time the user selects the new step.
Currently I'm using a picture box and have an image loaded from the disk at run time. So there are a few things I need to know here:
Is a picture box the best thing to use for this purpose or is there another control that would better suit?
How do embed the images in the executable and load them from there instead of a file that exists on disk.
How do I load a new image (I'm guessing that this will be fairly obvois if I can crack point 2)?
I've seen a few answers which relate to C# but I've not seen anything which looks like it translates to doing things in a C++/CLI app. Any suggestions would be very welcome.
Well it may not be the best solution, but the following works.
Create a new Windows Forms Application
Add these libraries to your linker settings (Project Proerties -> Link -> Input -> Additional Dependencies):
User32.lib Gdi32.lib
Add these headers:
#include <windows.h>
#include "resource.h"
Add these namespaces:
using namespace System::Reflection;
using namespace System::Runtime::InteropServices;
Add a pair of bitmaps to your resources and call them IDB_BITMAP1 and IDB_BITMAP2.
Add a picture box called m_pictureBox1.
Add a button and double-click the button to add an on-click handler:
System::Void button1_Click(System::Object^ sender, System::EventArgs^ e)
{
// Remove any previously stored images
if(m_pictureBox1->Image != nullptr)
{
delete m_pictureBox1->Image;
}
// Pick a new bitmap
static int resource = IDB_BITMAP1;
if( resource == IDB_BITMAP2)
{
resource = IDB_BITMAP1;
}
else
{
resource = IDB_BITMAP2;
}
// Get the primary module
Module^ mod = Assembly::GetExecutingAssembly()->GetModules()[0];
// Get the instance handle
IntPtr hinst = Marshal::GetHINSTANCE(mod);
// Get the bitmap as unmanaged
HANDLE hbi = LoadImage((HINSTANCE) hinst.ToPointer(),MAKEINTRESOURCE(resource),IMAGE_BITMAP,0,0,LR_DEFAULTCOLOR);
// import the unmanaged bitmap into the managed side
Bitmap^ bi = Bitmap::FromHbitmap(IntPtr(hbi));
// insert the bitmap into the picture box
m_pictureBox1->Image = bi;
// Free up the unmanaged bitmap
DeleteObject(hbi);
// Free up the instance and module
delete hinst;
delete mod;
}
..et voila the bitmaps are stored neatly in you app and each time you click the button the images will swap.

Is it possible to show/hide UserControls within a Silverlight XAP file from JavaScript?

I've created a Silverlight project that produces [something].xap file to package a few silverlight UserControls. I would like to manipulate that .xap file through the use of javascript in the browser to show and hide user controls based upon java script events.
Is it possible to do this?
If so any sample could or links to documentation would be appreciated.
Thanks in advance
Kevin
Here's my solution...not sure if it's the "best-practices" way...comments????
In the App class within my Silverlight application I have the following code:
private Page _page = null;
private void Application_Startup(object sender, StartupEventArgs e)
{
_page = new Page();
this.RootVisual = _page;
HtmlPage.RegisterScriptableObject("App", this);
}
Also to the App class I add a [ScriptableMember] to be called from JavaScript
[ScriptableMember]
public void ShowTeamSearch(Guid ctxId, Guid teamId)
{
_page.ShowTeamSearcher(ctxId, teamId);
}
The Page class is the default one that get's created within the Silverlight Control project, it really doesn't have any UI or logic, it's just used to swap in/out the views.
Login oLogin;
TeamSearcher oSearcher;
public Page()
{
InitializeComponent();
oLogin = new Login();
oSearcher = new TeamSearcher();
oLogin.Visibility = Visibility;
this.LayoutRoot.Children.Add(oLogin);
}
Also a method is added to show/hide the views...this could/will probably get more advanced/robust with animations etc...but this shows the basic idea:
public void ShowTeamSearcher(Guid ctxId, Guid teamId)
{
oSearcher.UserTeamId = teamId;
oSearcher.UserContextId = ctxId;
LayoutRoot.Children.Remove(oLogin);
LayoutRoot.Children.Add(oSearcher);
}
Then to invoke this in the JavaScript after assigning the id of oXaml to the instance of the silverlight host.
var slControl = document.getElementById('oXaml');
slControl.Content.App.ShowTeamSearch(sessionId, teamId);
This seems to work and isn't all that bad of a solution, but there might be something better...thoughts?
Here is a my collections of my links for this subject.
Javascript communication to
Silverlight 2.0
Silverlight
interoperability
Silverlight
and JavaScript Interop Basics

Resources