Using Google Earth API in Winforms (.net 4.0) - winforms

Are there any samples for setting up Winforms (or WPF) that use the Google Earth API? I see a lot of deprecated stuff (FC.GEPlugins). I know that I need a webbrowser control, but I am not sure how to even assign this to the plugin.
Would love a simple application that shows how to pass a latitude/longitude to the plugin and put a marker on the location.
Thanks!

you can achieve that by building a KML file form your code and run it ,its quit simple.
Here an C# code example :
StreamWriter _writer = new StreamWriter("C:\Map.KML");
_writer.WriteLine("<?xml version=\"1.0\" encoding=\"UTF-8\"?><kml xmlns=\"http://www.opengis.net/kml/2.2\">");
_writer.WriteLine("<Document>");
_writer.WriteLine("<Placemark>");
_writer.WriteLine("<Style>");
_writer.WriteLine("<IconStyle>");
_writer.WriteLine("<color>ccaa00ee</color>");
_writer.WriteLine("</IconStyle>");
_writer.WriteLine("<LabelStyle>");
_writer.WriteLine("<color>ccaa00ee</color>");
_writer.WriteLine("</LabelStyle>");
_writer.WriteLine("</Style>");
_writer.WriteLine("<name>");
_writer.WriteLine(your location name);
_writer.WriteLine("</name>");
_writer.WriteLine("<Point>");
_writer.WriteLine("<coordinates>" + your longitude + "," + your latitude + "</coordinates>");
_writer.WriteLine("</Point>");
_writer.WriteLine("</Placemark>");
}
_writer.WriteLine("</Document>");
_writer.WriteLine("</kml>");
_writer.Close();
System.Diagnostics.Process.Start("C:\Map.KML");

after I posted this I realized you asked for google earth not google maps - this is an example of google maps. hopefully it can help some
create a form
'Using the control
Public Class Mapping
Dim wide As Integer
Dim high As Integer
Private GoogleControl1 As GoogleControl
Sub New()
' This call is required by the Windows Form Designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
GoogleControl1 = New GoogleControl() With {.Dock = DockStyle.Fill}
Me.Controls.Add(GoogleControl1)
End Sub
End class
create a class
'The Control
'The class needs to be marked as com visible so the
'script in the GoogleMap.htm can call some of the subs.
<System.Runtime.InteropServices.ComVisibleAttribute(True)> _
Public Class GoogleControl : Inherits UserControl
Dim cnn As New MySqlConnection()
Dim cmd As New MySqlCommand
Dim adptr As New MySqlDataAdapter
Dim current As String
Dim filltab As New DataTable
Dim pop As Integer
Private WebBrowser1 As WebBrowser
Private StatusStrip1 As StatusStrip
Private StatusButtonDelete As ToolStripButton
Private StatusLabelLatLng As ToolStripStatusLabel
Private lastupdated As ToolStripStatusLabel
Private InitialZoom As Integer
Private timer2 As Timer
Private InitialLatitude As Double
Private InitialLongitude As Double
Private components As System.ComponentModel.IContainer
Private InitialMapType As GoogleMapType
Dim mapcontains As New System.Collections.Generic.HashSet(Of String)
'I use this enum to store the current map
'type into the application's settings.
'So when the user closes the map on Satellite
'mode it will be on Satellite mode the next
'time they open it.
Public Enum GoogleMapType
None
RoadMap
Terrain
Hybrid
Satellite
End Enum
Sub New()
MyBase.New()
WebBrowser1 = New WebBrowser
StatusStrip1 = New StatusStrip
StatusButtonDelete = New ToolStripButton
StatusLabelLatLng = New ToolStripStatusLabel
lastupdated = New ToolStripStatusLabel
WebBrowser1.Dock = DockStyle.Fill
timer2 = New Timer() With {.Interval = 10000, .Enabled = True}
WebBrowser1.AllowWebBrowserDrop = False
WebBrowser1.IsWebBrowserContextMenuEnabled = False
WebBrowser1.WebBrowserShortcutsEnabled = False
WebBrowser1.ObjectForScripting = Me
WebBrowser1.ScriptErrorsSuppressed = True
AddHandler WebBrowser1.DocumentCompleted, AddressOf WebBrowser1_DocumentCompleted
StatusStrip1.Dock = DockStyle.Bottom
' StatusStrip1.Items.Add(StatusButtonDelete)
' StatusStrip1.Items.Add(StatusLabelLatLng)
StatusStrip1.Items.Add(lastupdated)
StatusButtonDelete.Text = "Delete Markers"
' AddHandler StatusButtonDelete.Click, AddressOf StatusButtonDelete_Click
AddHandler timer2.Tick, AddressOf Timer2_Tick
Me.Controls.Add(WebBrowser1)
Me.Controls.Add(StatusStrip1)
'The default map settings.
InitialZoom = 10
InitialLatitude = 36.8438126
InitialLongitude = -76.2862457
InitialMapType = GoogleMapType.RoadMap
End Sub
Sub New(ByVal zoom As Integer, ByVal lat As Double, ByVal lng As Double, ByVal mapType As GoogleMapType)
'This constructor could be used to start the map with different values
'other than the default settings.
Me.New()
InitialZoom = zoom
InitialLatitude = lat
InitialLongitude = lng
InitialMapType = mapType
End Sub
Private Sub GoogleControl_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
'Load the htm doc into the webrowser.
'When it completes, intialize the map.
WebBrowser1.DocumentText = My.Computer.FileSystem.ReadAllText("GoogleMap.htm")
End Sub
Private Sub WebBrowser1_DocumentCompleted(ByVal sender As Object, ByVal e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs)
'Initialize the google map with the initial settings.
'The Initialize script function takes four parameters.
'zoom, lat, lng, maptype. Call the script passing the
'parameters in.
WebBrowser1.Document.InvokeScript("Initialize", New Object() {InitialZoom, InitialLatitude, InitialLongitude, CInt(InitialMapType)})
End Sub
Public Sub Map_MouseMove(ByVal lat As Double, ByVal lng As Double)
'Called from the GoogleMap.htm script when ever the mouse is moved.
StatusLabelLatLng.Text = "lat/lng: " & CStr(Math.Round(lat, 4)) & " , " & CStr(Math.Round(lng, 4))
End Sub
Public Sub Map_Click(ByVal lat As Double, ByVal lng As Double)
'Add a marker to the map.
' Dim MarkerName As String = InputBox("Enter a Marker Name", "New Marker")
' If Not String.IsNullOrEmpty(MarkerName) Then
'The script function AddMarker takes three parameters
'name,lat,lng. Call the script passing the parameters in.
' WebBrowser1.Document.InvokeScript("AddMarker", New Object() {MarkerName, lat, lng})
' End If
End Sub
Public Sub Map_Idle()
'Would be a good place to load your own custom markers
'from data source
End Sub
' Private Sub StatusButtonDelete_Click(ByVal sender As Object, ByVal e As EventArgs)
'Call the DeleteMarkers script in the htm doc.
' WebBrowser1.Document.InvokeScript("DeleteMarkers")
' End Sub
Private Sub InitializeComponent()
Me.SuspendLayout()
'
'GoogleControl
'
Me.Name = "GoogleControl"
Me.ResumeLayout(False)
End Sub
End Class
then create a html file called GoogleMap.htm
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<style type="text/css">
html {
height: 100%;
}
body {
height: 100%;
margin: 0;
padding: 0;
}
#map_canvas {
height: 100%;
}
</style>
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"> </script>
<script type="text/javascript">
var map;
var Markers = [];
function Initialize(zoomLevel, lat, lng, type) {
//Get the type of map to start.
//Need to convert the GoogleMapType enum
//to an actual Google Map Type
var MapType;
switch (type) {
case 1:
MapType = google.maps.MapTypeId.ROADMAP;
break;
case 2:
MapType = google.maps.MapTypeId.TERRAIN;
break;
case 3:
MapType = google.maps.MapTypeId.HYBRID;
break;
case 4:
MapType = google.maps.MapTypeId.SATELLITE;
break;
default:
MapType = google.maps.MapTypeId.ROADMAP;
};
//Create an instance of the map with the lat, lng, zoom, and
//type passed in
var myLatlng = new google.maps.LatLng(lat, lng);
var myOptions = { zoom: zoomLevel, center: myLatlng, mapTypeId: MapType };
var MarkerSize = new google.maps.Size(48, 48);
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
google.maps.event.addListener(map, 'click', Map_Click);
google.maps.event.addListener(map, 'mousemove', Map_MouseMove);
google.maps.event.addListener(map, 'idle', Map_Idle);
}
function Map_Click(e) {
window.external.Map_Click(e.latLng.lat(), e.latLng.lng());
}
function Map_MouseMove(e) {
window.external.Map_MouseMove(e.latLng.lat(), e.latLng.lng());
}
function Map_Idle() {
window.external.Map_Idle();
}
function DeleteMarkers() {
if (Markers) {
for (i in Markers) {
Markers[i].setMap(null);
google.maps.event.clearInstanceListeners(Markers[i]);
Markers[i] = null;
}
Markers.length = 0;
}
}
function AddMarker(name, lat, lng) {
var MarkerLatLng = new google.maps.LatLng(lat, lng);
var MarkerOption = { map: map, position: MarkerLatLng, title: name };
var Marker = new google.maps.Marker(MarkerOption);
Markers.push(Marker);
MarkerLatLng = null;
MarkerOption = null;
}
</script>
</head>
<body>
<div id="map_canvas" style="width: 100%; height: 100%">
</div>
</body>
</html>
congratulations you are in business - load the form and you should have a map looking at the center of the Hampton Roads, VA area. to change the location go to
InitialZoom = 10
InitialLatitude = 36.8438126
InitialLongitude = -76.2862457
the higher the zoom number the closer you will be to streetview
initial lat and long must be in decimal
to add a marker you would use vb.net
WebBrowser1.Document.InvokeScript("AddMarker", New Object() {"Description entered here", lat, long})
you could easily add 2 textboxes and a button and run this script with the lat and long from the textboxes
good luck

Why do you say deprecated? You can use the FC.GEPluginCtrls.GEWebBrowser in both winforms and WPF - it inherits from the standard webbrowser control and can be used wherever that can.
To load the plugin, add a marker and fly to the location you would simply do.
namespace ExampleFormTest
{
using System;
using System.Windows.Forms;
using FC.GEPluginCtrls;
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
geWebBrowser1.LoadEmbededPlugin();
// Handle the he PluginReady event
geWebBrowser1.PluginReady += (o, e) =>
{
// Here you can now use 'ge' exactly as you would
// in the native javascript api.
dynamic ge = e.ApiObject;
// create a placemark at (52, -2) look at it
var placemark = KmlHelpers.CreatePlacemark(ge, 'myPm', 52, -2);
GEHelpers.FlyToObject(ge, placemark);
};
}
}
}
There is an example of setting up the controls here.

Related

Get PropertyName of WPF Control

I have a ListBox that I fill with custom objects, these objects have the following properties as seen below:
Public Class VariableClass
Public Property Content As String
Public Property myNameLabel As New Label
Public Property myNameTextBox As New ComboBox
Public Property myTypeLabel As New Label
Public Property myTypeTextBox As New ComboBox
Public Overrides Function ToString() As String
Return Content.ToString()
End Function
End Class
When the user clicks on any of the custom objects, the properties of the custom objects that are WPF controls are pragmatically created in a stackpanel.
I do it like this:
If Flowchart.SelectedItem.GetType.Name = "VariableClass" Then
SetLabelProperties(Flowchart.SelectedItem.myNameLabel, "Name:", "25", LabelPanel.Width, HorizontalAlignment.Center)
SetLabelProperties(Flowchart.SelectedItem.myTypeLabel, "Type:", "25", LabelPanel.Width, HorizontalAlignment.Center)
SetComboBoxProperties(Flowchart.SelectedItem.myNameTextBox, Flowchart.SelectedItem.myNameTextBox.Text, "25", ValuePanel.Width, VerticalContentAlignment.Center, True, True)
SetComboBoxProperties(Flowchart.SelectedItem.myTypeTextBox, Flowchart.SelectedItem.myTypeTextBox.Text, "25", ValuePanel.Width, VerticalContentAlignment.Center, True, True)
AddPropertiesInStackPanel(Flowchart.SelectedItem)
End if
The functions:
Function SetLabelProperties(myLabel As Label, myName As String, myHeight As String, myWidth As String, myHorizontalAlignment As HorizontalAlignment)
myLabel.Content = myName
myLabel.Height = myHeight
myLabel.Width = myWidth
myLabel.HorizontalContentAlignment = myHorizontalAlignment
End Function
Function SetComboBoxProperties(myComboBox As ComboBox, myName As String, myHeight As String, myWidth As String, myVerticalAlignment As VerticalAlignment, Editable As Boolean, SearchEnabled As Boolean)
myComboBox.IsEditable = Editable
myComboBox.IsTextSearchEnabled = SearchEnabled
myComboBox.Text = myName
myComboBox.Height = myHeight
myComboBox.Width = myWidth
myComboBox.VerticalContentAlignment = myVerticalAlignment
Dim myDouble As Double = 0
Dim myStatic As ResourceKey = SystemParameters.VerticalScrollBarWidthKey
myComboBox.Resources.Add(myStatic, myDouble)
End Function
Function SetTextBoxProperties(myTextBox As TextBox, myName As String, myHeight As String, myWidth As String, myVerticalAlignment As VerticalAlignment)
myTextBox.Text = myName
myTextBox.Height = myHeight
myTextBox.Width = myWidth
myTextBox.VerticalContentAlignment = myVerticalAlignment
End Function
Function AddPropertiesInStackPanel(myObject As Object)
Dim info() As PropertyInfo = myObject.GetType().GetProperties()
For Each item In info
Dim myElementSplit = Split(item.PropertyType.FullName, ".")(UBound(Split(item.PropertyType.FullName, ".")))
If myElementSplit = "Label" Then
LabelPanel.Children.Add(item.GetValue(myObject))
LabelPanel.Children.Add(New Separator With {.Height = 1, .Opacity = 0})
ElseIf myElementSplit = "ComboBox" Then
ValuePanel.Children.Add(item.GetValue(myObject))
ValuePanel.Children.Add(New Separator With {.Height = 1, .Opacity = 0})
ElseIf myElementSplit = "TextBox" Then
ValuePanel.Children.Add(item.GetValue(myObject))
ValuePanel.Children.Add(New Separator With {.Height = 1, .Opacity = 0})
End If
Next
End Function
I have tried this event that triggers whenever the user types into a ComboBox in the stackpanel.
Private Sub ValuePanel_PreviewKeyDown(sender As Object, e As KeyEventArgs) Handles ValuePanel.PreviewKeyDown
Dim myElement = e.OriginalSource
Dim myVar = GetValue(myElement).GetType().GetProperty("PropertyName")
End Sub
But myElement is not a DependencyProperty and it cannot be cast to one.
The control that raises the PreviewKeyDown doesn't know which propery of your custom object it "came" from. You can however store this information in the Tag property of the control, e.g.:
myNameTextBox.Tag = "myNameLabel"
...and then retrieve it in the event handler using this property:
Private Sub ValuePanel_PreviewKeyDown(sender As Object, e As KeyEventArgs)
Dim myElement = CType(e.OriginalSource, FrameworkElement)
Dim propertyName = myElement.Tag.ToString()
End Sub

Top ListView in SplitContainer won't add vertical scrollbar

I have a Winforms app with two ListViews in a SplitContainer.
When I drag the splitter to hide part of the Panel2 ListView items, it automatically adds a vertical scrollbar.
When I drag the splitter to hide part of the Panel1 ListView items, it does not add a vertical scrollbar.
Changing which ListView is in which Panel has the same behavior. It's as if something about the SplitContainer or its panels is controlling whether the vertical scrollbar is added to the ListView in Panel1 or not. How to make whichever ListView is in the top Panel1 also automatically add the vertical scrollbar?
To replicate, create a simple Winforms application with one form. Here is my form code followed by the designer form code.
Public Class Form1
Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles Me.Shown
Timer1.Enabled = True
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
Try
Timer1.Enabled = False
TechDateList.BeginUpdate()
TechDateList.Items.Clear()
StopsList.BeginUpdate()
StopsList.Items.Clear()
For i As Integer = 1 To 5
Dim techItem = New ListViewItem
techItem.UseItemStyleForSubItems = False
techItem.SubItems(0).Text = Date.Now.ToString("MMM dd, yyyy")
techItem.SubItems.Add(String.Format("Tech {0}", i))
TechDateList.Items.Add(techItem)
Next
For i As Integer = 1 To 5
Dim stopItem = New ListViewItem
stopItem.UseItemStyleForSubItems = False
stopItem.SubItems(0).Text = Choose(i, "AAA", "BBB", "CCC", "DDD", "EEE")
stopItem.SubItems.Add(String.Format("Stop {0}", i))
StopsList.Items.Add(stopItem)
Next
Catch ex As Exception
MsgBox(ex.ToString(), MsgBoxStyle.Critical + MsgBoxStyle.OkOnly, "Timer1_Tick Error 1")
Finally
TechDateList.EndUpdate()
StopsList.EndUpdate()
End Try
Try
ListSplitter.Panel1Collapsed = False
ListSplitter.SplitterDistance = 125
ListSplitter.SplitterWidth = 6
TechDateList.Items.Item(0).Selected = True
Catch ex As Exception
MsgBox(ex.ToString(), MsgBoxStyle.Critical + MsgBoxStyle.OkOnly, "Timer1_Tick Error 2")
End Try
End Sub
End Class
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class Form1
Inherits System.Windows.Forms.Form
'Form overrides dispose to clean up the component list.
<System.Diagnostics.DebuggerNonUserCode()> _
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub
'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer
'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
<System.Diagnostics.DebuggerStepThrough()> _
Private Sub InitializeComponent()
Me.components = New System.ComponentModel.Container()
Me.ListSplitter = New System.Windows.Forms.SplitContainer()
Me.TechDateList = New System.Windows.Forms.ListView()
Me.UInitial = CType(New System.Windows.Forms.ColumnHeader(), System.Windows.Forms.ColumnHeader)
Me.SchedDate = CType(New System.Windows.Forms.ColumnHeader(), System.Windows.Forms.ColumnHeader)
Me.StopsList = New System.Windows.Forms.ListView()
Me.StopNum = CType(New System.Windows.Forms.ColumnHeader(), System.Windows.Forms.ColumnHeader)
Me.StopName = CType(New System.Windows.Forms.ColumnHeader(), System.Windows.Forms.ColumnHeader)
Me.Timer1 = New System.Windows.Forms.Timer(Me.components)
CType(Me.ListSplitter, System.ComponentModel.ISupportInitialize).BeginInit()
Me.ListSplitter.Panel1.SuspendLayout()
Me.ListSplitter.Panel2.SuspendLayout()
Me.ListSplitter.SuspendLayout()
Me.SuspendLayout()
'
'ListSplitter
'
Me.ListSplitter.Dock = System.Windows.Forms.DockStyle.Fill
Me.ListSplitter.FixedPanel = System.Windows.Forms.FixedPanel.Panel1
Me.ListSplitter.Location = New System.Drawing.Point(0, 0)
Me.ListSplitter.Name = "ListSplitter"
Me.ListSplitter.Orientation = System.Windows.Forms.Orientation.Horizontal
'
'ListSplitter.Panel1
'
Me.ListSplitter.Panel1.Controls.Add(Me.TechDateList)
Me.ListSplitter.Panel1Collapsed = True
Me.ListSplitter.Panel1MinSize = 0
'
'ListSplitter.Panel2
'
Me.ListSplitter.Panel2.Controls.Add(Me.StopsList)
Me.ListSplitter.Size = New System.Drawing.Size(384, 261)
Me.ListSplitter.SplitterDistance = 25
Me.ListSplitter.SplitterWidth = 1
Me.ListSplitter.TabIndex = 1
'
'TechDateList
'
Me.TechDateList.Anchor = CType(((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom) _
Or System.Windows.Forms.AnchorStyles.Left), System.Windows.Forms.AnchorStyles)
Me.TechDateList.Columns.AddRange(New System.Windows.Forms.ColumnHeader() {Me.UInitial, Me.SchedDate})
Me.TechDateList.FullRowSelect = True
Me.TechDateList.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.None
Me.TechDateList.HideSelection = False
Me.TechDateList.LabelWrap = False
Me.TechDateList.Location = New System.Drawing.Point(4, 0)
Me.TechDateList.Margin = New System.Windows.Forms.Padding(0)
Me.TechDateList.MultiSelect = False
Me.TechDateList.Name = "TechDateList"
Me.TechDateList.ShowGroups = False
Me.TechDateList.Size = New System.Drawing.Size(258, 166)
Me.TechDateList.TabIndex = 0
Me.TechDateList.UseCompatibleStateImageBehavior = False
Me.TechDateList.View = System.Windows.Forms.View.Details
'
'UInitial
'
Me.UInitial.Text = "Route"
Me.UInitial.TextAlign = System.Windows.Forms.HorizontalAlignment.Center
Me.UInitial.Width = 100
'
'SchedDate
'
Me.SchedDate.Text = "Job Date"
Me.SchedDate.Width = 133
'
'StopsList
'
Me.StopsList.Anchor = CType(((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom) _
Or System.Windows.Forms.AnchorStyles.Left), System.Windows.Forms.AnchorStyles)
Me.StopsList.Columns.AddRange(New System.Windows.Forms.ColumnHeader() {Me.StopNum, Me.StopName})
Me.StopsList.FullRowSelect = True
Me.StopsList.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.None
Me.StopsList.HideSelection = False
Me.StopsList.LabelWrap = False
Me.StopsList.Location = New System.Drawing.Point(4, 0)
Me.StopsList.Margin = New System.Windows.Forms.Padding(0)
Me.StopsList.MultiSelect = False
Me.StopsList.Name = "StopsList"
Me.StopsList.ShowGroups = False
Me.StopsList.Size = New System.Drawing.Size(258, 252)
Me.StopsList.TabIndex = 0
Me.StopsList.UseCompatibleStateImageBehavior = False
Me.StopsList.View = System.Windows.Forms.View.Details
'
'StopNum
'
Me.StopNum.Text = "000"
Me.StopNum.TextAlign = System.Windows.Forms.HorizontalAlignment.Center
Me.StopNum.Width = 34
'
'StopName
'
Me.StopName.Text = "Stop Name"
Me.StopName.Width = 199
'
'Timer1
'
Me.Timer1.Interval = 250
'
'Form1
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(384, 261)
Me.Controls.Add(Me.ListSplitter)
Me.Name = "Form1"
Me.Text = "Form1"
Me.ListSplitter.Panel1.ResumeLayout(False)
Me.ListSplitter.Panel2.ResumeLayout(False)
CType(Me.ListSplitter, System.ComponentModel.ISupportInitialize).EndInit()
Me.ListSplitter.ResumeLayout(False)
Me.ResumeLayout(False)
End Sub
Friend WithEvents ListSplitter As SplitContainer
Friend WithEvents TechDateList As ListView
Friend WithEvents UInitial As ColumnHeader
Friend WithEvents SchedDate As ColumnHeader
Friend WithEvents StopsList As ListView
Friend WithEvents StopNum As ColumnHeader
Friend WithEvents StopName As ColumnHeader
Friend WithEvents Timer1 As Timer
End Class
From what I see in Designer code, TechDateList Height exceeds ListSplitter.Panel1 Height:
Me.ListSplitter.SplitterDistance = 25
Me.TechDateList.Size = New System.Drawing.Size(258, 166)
make sure that TechDateList fits Panel1 in Designer, e.g
Me.ListSplitter.SplitterDistance = 125
Me.TechDateList.Size = New System.Drawing.Size(258, 120)
and then resize will work as expected.
consider also docking TechDateList to Left - the list will get maximum possible Height and will resize with Panel1
I'm guessing that moving the splitter is resizing the ListView in Panel2 but not resizing the ListView in Panel1. I'm probably missing something simple somewhere. Regardless, if I add this code to the form, I get the desired results:
Private Sub ListSplitter_SplitterMoved(sender As Object, e As SplitterEventArgs) Handles ListSplitter.SplitterMoved
TechDateList.Height = ListSplitter.Panel1.Height
End Sub

ToolTip stays open

I need to show ToolTip on a certain control for a certain period of time, with this code I get the ToolTip to show, but it won't disappear:
Public Sub tooltipControl(ByVal kontrola As Object, ByVal opened As Boolean, ByVal Optional poruka As String = "", ByVal Optional boja As Object = Nothing)
Dim ellipse1 As New Ellipse
ellipse1.Height = 25
ellipse1.Width = 50
ellipse1.Fill = Brushes.Gray
ellipse1.HorizontalAlignment = HorizontalAlignment.Left
Dim bubble As New ToolTip
bubble.PlacementTarget = kontrola
bubble.Placement = PlacementMode.Bottom
ToolTipService.SetShowDuration(kontrola, 5000)
Dim bdec As New BulletDecorator
Dim littleEllipse As New Ellipse
littleEllipse.Height = 20
littleEllipse.Width = 20
littleEllipse.Fill = boja
bdec.Bullet = littleEllipse
Dim tipText As New TextBlock
tipText.Text = poruka
bdec.Child = tipText
bubble.Content = bdec
bubble.IsOpen = True
kontrola.ToolTip = bubble
End Sub
Set the duration on the elemtent the tooltip belongs to
ToolTipService.SetShowDuration(kontrola, 5000)
and add the tooltip before opening it
kontrola.ToolTip = bubble
bubble.IsOpen = True

VB.net WPF and Win 10 Toast Notifications

I'm trying to show toast notifications in Win 10 from vb.net WPF app.
1. I added <TargetPlatformVersion>10.0</TargetPlatformVersion> to .vbproj file in the <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> section.
2. I Added references to Windows.Data and Windows.UI
3. My code:
Class MainWindow
Private Sub BtnClick()
Dim ToastN As ToastNotification = New ToastNotification("Test", "This is test notification.")
End Sub
End Class
Public Class ToastNotification
Public Sub New(Title As String, Message As String)
Dim TempStr As String = $"<toast>
<visual>
<binding template='ToastGeneric'>
<text>{Title}</text>
<text>{Message}</text>
</binding>
</visual>
</toast>"
Dim xmlDoc As Windows.Data.Xml.Dom.XmlDocument = New Windows.Data.Xml.Dom.XmlDocument()
xmlDoc.LoadXml(TempStr)
Dim Toast As Windows.UI.Notifications.ToastNotification = New Windows.UI.Notifications.ToastNotification(xmlDoc)
Windows.UI.Notifications.ToastNotificationManager.CreateToastNotifier(Title).Show(Toast)
End Sub
End Class
Button's click event is set to BtnClick
Application runs but doesn't do anything. Everything works fine just ...createTestNotifier(Title).Show(Toast) doesn't work.
Could you please help.
What am I doing wrong?
Source ZIP
You have to create a shortcut of your app
with that:
private bool TryCreateShortcut()
{
string shortcutPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + string.Format("\\Microsoft\\Windows\\Start Menu\\Programs\\{0}.lnk", Path.GetFileNameWithoutExtension(AppDomain.CurrentDomain.FriendlyName));
if (!File.Exists(shortcutPath))
{
InstallShortcut(shortcutPath);
return true;
}
return false;
}
private void InstallShortcut(string shortcutPath)
{
// Find the path to the current executable
string exePath = Process.GetCurrentProcess().MainModule.FileName;
IShellLinkW newShortcut = (IShellLinkW)new CShellLink();
// Create a shortcut to the exe
ErrorHelper.VerifySucceeded(newShortcut.SetPath(exePath));
ErrorHelper.VerifySucceeded(newShortcut.SetArguments(""));
// Open the shortcut property store, set the AppUserModelId property
IPropertyStore newShortcutProperties = (IPropertyStore)newShortcut;
using (PropVariant appId = new PropVariant(Utility.APP_ID))
{
ErrorHelper.VerifySucceeded(newShortcutProperties.SetValue(SystemProperties.System.AppUserModel.ID, appId));
ErrorHelper.VerifySucceeded(newShortcutProperties.Commit());
}
// Commit the shortcut to disk
IPersistFile newShortcutSave = (IPersistFile)newShortcut;
ErrorHelper.VerifySucceeded(newShortcutSave.Save(shortcutPath, true));
}

WPF - Remove mnemonic function from textbox

Just discovered what is causing a HTML editor to throw the toys out when using a certain letter on a keyboard...
On the same page there are textboxes that contain things like html page name, title, navigate URL, menu text.... If one of the textboxes contains text with an underscore (say 'Test_Page') then the letter 'P' will not function in the HTML editor. I'm guessing (and could be way off base here as I didn't think textbox.txt could do this unlike Label.content) that WPF is taking the text entry and using it as a mnemonic key.. I do know that setting RecognisesAccessKey to false might cure it, but can't find a way to add that property or access ContentPresenter...
This is the class that I use to create the control and ideally would like to set it here
Public Class TBx
Inherits TextBox
Public Shared IsNewRecordProperty As DependencyProperty = DependencyProperty.Register("IsNewRecord", GetType(Boolean), GetType(TBx), New PropertyMetadata(New PropertyChangedCallback(AddressOf IsNewRecordChanged)))
Public Property IsNewRecord As Boolean
Get
Return GetValue(IsNewRecordProperty)
End Get
Set(value As Boolean)
SetValue(IsNewRecordProperty, value)
End Set
End Property
Protected Overrides Sub OnInitialized(e As System.EventArgs)
MyBase.OnInitialized(e)
VerticalAlignment = Windows.VerticalAlignment.Center
HorizontalAlignment = Windows.HorizontalAlignment.Left
BorderBrush = New SolidColorBrush(Colors.Silver)
Height = 22
SpellCheck.IsEnabled = True
UndoLimit = 0
If IsNewRecord = True Then
BorderThickness = New Thickness(1)
IsReadOnly = False
Background = New SolidColorBrush(Colors.White)
Else
BorderThickness = New Thickness(0)
IsReadOnly = True
Background = New SolidColorBrush(Colors.Transparent)
End If
End Sub
Private Shared Sub IsNewRecordChanged(sender As DependencyObject, e As DependencyPropertyChangedEventArgs)
Dim vControl As TBx = TryCast(sender, TBx)
Dim vBoolean As Boolean = e.NewValue
If vBoolean = True Then
vControl.BorderThickness = New Thickness(1)
vControl.IsReadOnly = False
vControl.Background = New SolidColorBrush(Colors.White)
Else
vControl.BorderThickness = New Thickness(0)
vControl.IsReadOnly = True
vControl.Background = New SolidColorBrush(Colors.Transparent)
End If
End Sub
End Class
Thank you
Couldn't find an easy way to do this from the class, but this works on the page
Dim CP As New ContentPresenter
CP.RecognizesAccessKey = False
Then add the TextBox to the ContentPresenter
Case 1
vLabel.Text = "Page Name"
With vTB
.Width = 200
.Name = vName & "PageNameTB"
.ToolTip = "This is the short name for the page"
.IsNewRecord = IsNewRecord
End With
CP.Content = vTB
The add the CP to the grid
RegisterControl(SecurePage_Grid, vTB)
Grid.SetColumn(vLabel, 0)
Grid.SetRow(vLabel, i)
If i = 1 Then
Grid.SetRow(CP, i)
Grid.SetColumn(CP, 1)
Else
Grid.SetRow(vTB, i)
Grid.SetColumn(vTB, 1)
End If
vGrid.Children.Add(vLabel)
If i = 1 Then
vGrid.Children.Add(CP)
Else
vGrid.Children.Add(vTB)
End If

Resources