Displaying multiple pushpins on Bing Maps WPF - wpf

Currently when I load my program Bing Maps will only load the first pushpin onto the map, for my example I have 4 pushpins which should be displayed when the application is loaded, what additional code would I add in order to make it complete all four.
In addition I have a couple of questions if you don't mind answering
Do I need to use a loop for each location?
Do I have to give each one an individual name? (Pin)
Can I link a access database instead of copying the locations across?
Is it possible to hide or remove pushpins when a button is clicked?
Dim Pin = New Microsoft.Maps.MapControl.WPF.Pushpin()
UserControl11.BingMap.Children.Add(Pin)
Pin.Location = (New Location(55.852663, -2.3889276))
Pin.Location = (New Location(55.956023, -3.1607265))
Pin.Location = (New Location(54.840279, -3.2886766))
Pin.Location = (New Location(52.819511, -1.8851815))

If it is just these 4 pins you want to create, then you can use the following code:
Dim Pin = New Microsoft.Maps.MapControl.WPF.Pushpin()
Pin.Location = (New Location(55.852663, -2.3889276))
UserControl11.BingMap.Children.Add(Pin)
Dim Pin2 = New Microsoft.Maps.MapControl.WPF.Pushpin()
Pin2.Location = (New Location(55.956023, -3.1607265))
UserControl11.BingMap.Children.Add(Pin2)
Dim Pin3 = New Microsoft.Maps.MapControl.WPF.Pushpin()
Pin3.Location = (New Location(54.840279, -3.2886766))
UserControl11.BingMap.Children.Add(Pin3)
Dim Pin4 = New Microsoft.Maps.MapControl.WPF.Pushpin()
Pin4.Location = (New Location(52.819511, -1.8851815))
UserControl11.BingMap.Children.Add(Pin4)
Alternatively, if your location data is changing or you have an array/list of location information you can loop through, create pushpins and add them to the map like this:
Dim myLocations(4) As Location
myLocations(0) = New Location(55.852663, -2.3889276)
myLocations(1) = New Location(55.956023, -3.1607265)
myLocations(2) = New Location(54.840279, -3.2886766)
myLocations(3) = New Location(52.819511, -1.8851815)
For index = 0 to myLocations.Length - 1
Dim Pin = New Microsoft.Maps.MapControl.WPF.Pushpin()
Pin.Location = myLocations(index)
UserControl11.BingMap.Children.Add(Pin)
Next

Related

Hide some points in Oxyplot Line series

I need to show/hide some data points in oxyplot line series. Is it possible?
Though some markers are invisible, the line should go through the invisible markers.
You could make use of two series to achieve this. The first one would draw the complete points (and line) without the marker. The second series would draw the visible points(with marker,but with line style set to none). For Example
DataPoint[] points = new DataPoint[]
{
new DataPoint(1,12),
new DataPoint(2,10),
new DataPoint(3,9),
new DataPoint(4,13),
new DataPoint(5,14),
new DataPoint(6,10)
};
var seriesComplete = new OxyPlot.Series.LineSeries();
seriesComplete.Points.AddRange(points);
var seriesVisible = new OxyPlot.Series.LineSeries();
seriesVisible.Points.AddRange(points.Where(x => x.Y % 2 == 0));
seriesVisible.MarkerFill = OxyColors.Blue;
seriesVisible.MarkerType = MarkerType.Circle;
seriesVisible.MarkerSize = 10;
seriesVisible.LineStyle = LineStyle.None;
this.MyModel.Series.Add(seriesComplete);
this.MyModel.Series.Add(seriesVisible);
Result is attached as image

VB.NET dataset displaying database rows incorrectly

I would say I'm new to VB but I have been using it for over a year although for mainly small tasks (mostly school related). Anyway my current project is for my A-Level task and I need to be able to add, update, delete and read from a database. My current code allows this to happen but after a new record is added to my database the dataset in VB displays the rows differently. I have 3 tables: "PlayerInfo", "PlayerSkill" and "PlayerAbilities". when a new record is added; the new "PlayerInfo" information becomes the first row in my dataset while the "PlayerSkill" and "PlayerAbilities" become the last row. This causes all of the information to be improperly matched up. I was wondering if anyone else has had this problem and if they know how to solve it.
This shows the working code to add to my database.
If inc <> -1 Then
Dim cb1 As New OleDb.OleDbCommandBuilder(da1)
Dim cb2 As New OleDb.OleDbCommandBuilder(da2)
Dim cb3 As New OleDb.OleDbCommandBuilder(da3)
Dim dsNewRow1 As DataRow
Dim dsNewRow2 As DataRow
Dim dsNewRow3 As DataRow
Try
dsNewRow1 = ds1.Tables("Players").NewRow()
dsNewRow1.Item("Forename") = Forename.Text()
dsNewRow1.Item("Surname") = Surname.Text()
ds1.Tables("Players").Rows.Add(dsNewRow1)
da1.Update(ds1, "Players")
dsNewRow3 = ds3.Tables("Players").NewRow()
dsNewRow3.Item("Reactions") = Reactions.Text()
dsNewRow3.Item("Strength") = Strength.Text()
dsNewRow3.Item("Speed") = Speed.Text()
dsNewRow3.Item("Stamina") = Stamina.Text()
dsNewRow3.Item("Accuracy") = Accuracy.Text()
dsNewRow3.Item("Coordination") = Coordination.Text()
ds3.Tables("Players").Rows.Add(dsNewRow3)
da3.Update(ds3, "Players")
dsNewRow2 = ds2.Tables("Players").NewRow()
dsNewRow2.Item("RegularShot") = RegularShot.Text()
dsNewRow2.Item("ShortServe") = ShortServe.Text()
dsNewRow2.Item("FlickServe") = FlickServe.Text()
dsNewRow2.Item("Clear") = Clear.Text()
dsNewRow2.Item("Smash") = Smash.Text()
dsNewRow2.Item("DropShot") = DropShot.Text()
ds2.Tables("Players").Rows.Add(dsNewRow2)
da2.Update(ds2, "Players")
MsgBox("New Record added to the Database")
Commit.Enabled = False
AddNew.Enabled = True
Update.Enabled = True
Delete.Enabled = True
Catch
MsgBox("Error")
Me.Close()
End Try
End If
This shows the code that displays each of the dataset records inside different text boxes.
Try
Forename.Text = ds1.Tables("Players").Rows(inc).Item(1)
Surname.Text = ds1.Tables("Players").Rows(inc).Item(2)
Speed.Text = ds3.Tables("Players").Rows(inc).Item(3)
Strength.Text = ds3.Tables("Players").Rows(inc).Item(2)
Reactions.Text = ds3.Tables("Players").Rows(inc).Item(1)
Stamina.Text = ds3.Tables("Players").Rows(inc).Item(4)
Coordination.Text = ds3.Tables("Players").Rows(inc).Item(6)
Accuracy.Text = ds3.Tables("Players").Rows(inc).Item(5)
ShortServe.Text = ds2.Tables("Players").Rows(inc).Item(2)
FlickServe.Text = ds2.Tables("Players").Rows(inc).Item(3)
Clear.Text = ds2.Tables("Players").Rows(inc).Item(4)
Smash.Text = ds2.Tables("Players").Rows(inc).Item(5)
DropShot.Text = ds2.Tables("Players").Rows(inc).Item(6)
RegularShot.Text = ds2.Tables("Players").Rows(inc).Item(1)
Catch
MsgBox("Error")
Me.Close()
End Try
Sadly I do not currently have enough "Rep" to upload a picture of the dataset.
Also sorry if this is not enough information, I'm not really used to using forums and such.
I'm not entirely sure if this counts as an answer as I still don't know what caused the problem in the first case. Anyway I've got my code doing what I wanted by editing the SQL statements to display the rows in order of the primary key. ORDER BY [Player#]. I did have to change the name to just "Player" because the "CommandBuilder" doesn't like special characters.

DataSet created in code not Binding to ListView

I have a WPF User Control with a ListView in it that is created based on the DataSet that is passed to it:
public void PopulateList(DataSet ds) {
listView.View = CreateGridViewColumns(ds.Tables[0]);
listData.DataContext = ds.Tables[0];
}
private GridView CreateGridViewColumns(DataTable dt) {
// Create the GridView
var gv = new GridView {AllowsColumnReorder = true};
// Create the GridView Columns
foreach (DataColumn item in dt.Columns) {
var gvc = new GridViewColumn
{
DisplayMemberBinding = new Binding(item.ColumnName),
Header = item.ColumnName,
Width = Double.NaN
};
gv.Columns.Add(gvc);
}
return gv;
}
Now I create the user control in code and call it's PopulateList with the appropriate dataset and this is where the problems are starting:
If I pass in a dataset that was created from a call to the database the list view shows all the data but if i pass in a DataSet that i created in code the ListView shows the Columns but will not show the data
//This is a function that hides the DB call return type is DataSet
var dsPatientSmokingStatusHistory = DataRepository.PatientSmokingStatusProvider.GetHistory(PatientId);
//radGridViewPatientSmokingStatus.DataSource = dsPatientSmokingStatusHistory.Tables[0];
var dt = new DataTable();
string c1 = "Date".PadLeft(23).PadRight(23);
string c2 = "Status".PadLeft(20).PadRight(50);
dt.Columns.Add(c1);
dt.Columns.Add(c2);
int i = 0;
foreach (DataRow row in dsPatientSmokingStatusHistory.Tables[0].Rows) {
var dataRow = dt.NewRow();
dataRow[c1] = ((DateTime)row["Date"]).ToString("MM/dd/yyyy");
dataRow[c2] = row["Status"].ToString();
dt.Rows.Add(dataRow);
dt.Rows[i].AcceptChanges();
i++;
}
DataSet ds = new DataSet();
dt.TableName = "Table";
ds.Tables.Add(dt);
ds.AcceptChanges();
smokingStatusGrid.GridWidth = 455;
smokingStatusGrid.GridHight = 97;
//This line does not show data
smokingStatusGrid.PopulateGrid(ds);
//This line will show data
smokingStatusGrid.PopulateGrid(dsPatientSmokingStatusHistory);
Is there a difference between these two datasets that i don't know about that is preventing me from databinding to it?
Also the user control is being used as an ElementHost in a WinForms application (not sure if this makes a difference)
Your code says:
DisplayMemberBinding = new Binding(item.ColumnName)
This binding constructor takes a string paramter which as per MSDN is "The initial Path for the binding" and is of datatype System.Windows.PropertyPath. I guess, since system tries to find a property with the same name in your class, and your string (item.ColumnName) has spaces at start, it runs into a problem (properties can't start with a space).
Would recommend you to take off the padding that you are doing in column name of your table. Apply any padding/margins in the Header of your GridView.

MS Chart in WPF, Setting the DataSource is not creating the Series

Here I am trying to assign the datasource (using same code given in the sample application) and create a graph, only difference is i am doing it in WPF WindowsFormsHost. due to some reason the datasource is not being assigned properly and i am not able to see the series ("Series 1") being created. wired thing is that it is working in the Windows Forms application but not in the WPF one.
am i missing something and can somebody help me?
Thanks
<Window x:Class="SEDC.MDM.WinUI.WindowsFormsHostWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
xmlns:CHR="clr- namespace:System.Windows.Forms.DataVisualization.Charting;assembly=System.Windows.Forms.Dat aVisualization"
Title="HostingWfInWpf" Height="230" Width="338">
<Grid x:Name="grid1">
</Grid>
</Window>
private void drawChartDataBinding()
{
System.Windows.Forms.Integration.WindowsFormsHost host =
new System.Windows.Forms.Integration.WindowsFormsHost();
string fileNameString = #"C:\Users\Shaik\MSChart\WinSamples\WinSamples\data\chartdata.mdb";
// initialize a connection string
string myConnectionString = "PROVIDER=Microsoft.Jet.OLEDB.4.0;Data Source=" + fileNameString;
// define the database query
string mySelectQuery = "SELECT * FROM REPS;";
// create a database connection object using the connection string
OleDbConnection myConnection = new OleDbConnection(myConnectionString);
// create a database command on the connection using query
OleDbCommand myCommand = new OleDbCommand(mySelectQuery, myConnection);
Chart Chart1 = new Chart();
// set chart data source
Chart1.DataSource = myCommand;
// set series members names for the X and Y values
Chart1.Series"Series 1".XValueMember = "Name";
Chart1.Series"Series 1".YValueMembers = "Sales";
// data bind to the selected data source
Chart1.DataBind();
myCommand.Dispose();
myConnection.Close();
host.Child = Chart1;
this.grid1.Children.Add(host);
}
Shaik
With the following two changes, you can fix your code:
1 - Instead of
Chart1.Series"Series 1".XValueMember = "Name";
Chart1.Series"Series 1".YValueMembers = "Sales";
write
Chart1.Series["Series 1"].XValueMember = "Name";
Chart1.Series["Series 1"].YValueMembers = "Sales";
2 - Before the above code, insert the following lines:
Chart1.ChartAreas.Add("Default");
Chart1.Series.Add(new Series("Series 1"));

Printing a WPF FlowDocument

I'm building a demo app in WPF, which is new to me. I'm currently displaying text in a FlowDocument, and need to print it.
The code I'm using looks like this:
PrintDialog pd = new PrintDialog();
fd.PageHeight = pd.PrintableAreaHeight;
fd.PageWidth = pd.PrintableAreaWidth;
fd.PagePadding = new Thickness(50);
fd.ColumnGap = 0;
fd.ColumnWidth = pd.PrintableAreaWidth;
IDocumentPaginatorSource dps = fd;
pd.PrintDocument(dps.DocumentPaginator, "flow doc");
fd is my FlowDocument, and for now I'm using the default printer instead of allowing the user to specify print options. It works OK, except that after the document prints, the FlowDocument displayed on screen has changed to to use the settings I specified for printing.
I can fix this by manually resetting everything after I print, but is this the best way? Should I make a copy of the FlowDocument before I print it? Or is there another approach I should consider?
yes, make a copy of the FlowDocument before printing it. This is because the pagination and margins will be different. This works for me.
private void DoThePrint(System.Windows.Documents.FlowDocument document)
{
// Clone the source document's content into a new FlowDocument.
// This is because the pagination for the printer needs to be
// done differently than the pagination for the displayed page.
// We print the copy, rather that the original FlowDocument.
System.IO.MemoryStream s = new System.IO.MemoryStream();
TextRange source = new TextRange(document.ContentStart, document.ContentEnd);
source.Save(s, DataFormats.Xaml);
FlowDocument copy = new FlowDocument();
TextRange dest = new TextRange(copy.ContentStart, copy.ContentEnd);
dest.Load(s, DataFormats.Xaml);
// Create a XpsDocumentWriter object, implicitly opening a Windows common print dialog,
// and allowing the user to select a printer.
// get information about the dimensions of the seleted printer+media.
System.Printing.PrintDocumentImageableArea ia = null;
System.Windows.Xps.XpsDocumentWriter docWriter = System.Printing.PrintQueue.CreateXpsDocumentWriter(ref ia);
if (docWriter != null && ia != null)
{
DocumentPaginator paginator = ((IDocumentPaginatorSource)copy).DocumentPaginator;
// Change the PageSize and PagePadding for the document to match the CanvasSize for the printer device.
paginator.PageSize = new Size(ia.MediaSizeWidth, ia.MediaSizeHeight);
Thickness t = new Thickness(72); // copy.PagePadding;
copy.PagePadding = new Thickness(
Math.Max(ia.OriginWidth, t.Left),
Math.Max(ia.OriginHeight, t.Top),
Math.Max(ia.MediaSizeWidth - (ia.OriginWidth + ia.ExtentWidth), t.Right),
Math.Max(ia.MediaSizeHeight - (ia.OriginHeight + ia.ExtentHeight), t.Bottom));
copy.ColumnWidth = double.PositiveInfinity;
//copy.PageWidth = 528; // allow the page to be the natural with of the output device
// Send content to the printer.
docWriter.Write(paginator);
}
}
You can use the code from the URL below, it wraps the flow document in a fixed document and prints that, the big advantage is that you can use it to add margin, headers and footers.
https://web.archive.org/web/20150502085246/http://blogs.msdn.com:80/b/fyuan/archive/2007/03/10/convert-xaml-flow-document-to-xps-with-style-multiple-page-page-size-header-margin.aspx
The following works with both text and non-text visuals:
//Clone the source document
var str = XamlWriter.Save(FlowDoc);
var stringReader = new System.IO.StringReader(str);
var xmlReader = XmlReader.Create(stringReader);
var CloneDoc = XamlReader.Load(xmlReader) as FlowDocument;
//Now print using PrintDialog
var pd = new PrintDialog();
if (pd.ShowDialog().Value)
{
CloneDoc.PageHeight = pd.PrintableAreaHeight;
CloneDoc.PageWidth = pd.PrintableAreaWidth;
IDocumentPaginatorSource idocument = CloneDoc as IDocumentPaginatorSource;
pd.PrintDocument(idocument.DocumentPaginator, "Printing FlowDocument");
}
I am also generating a WPF report off a Flow document, but I am purposely using the flow document as a print preview screen. I there for want the margins to be the same. You can read about how I did this here.
In your scenario I'm thinking why not just make a copy of your settings, instead of the entire flow document. You can then re-apply the settings if you wish to return the document back to it's original state.

Resources