Wednesday, December 8, 2010

Migrating ESRI Business Analyst API from Silverlight 3 to Silverlight 4

When you install ArcGIS Silverlight API v2.1 and then try to use the ESRI Business Analyst API DLL (ESRI.ArcGIS.Client.BAO.dll) which is still (8 Dec 2010) version 1.1.0.97 then application will throw the following error. This error will appear when you attempt to authenticate with ESRI BAO API and get a token.
{System.Exception: Error processing task results ---> System.MissingMethodException: Method not found: 'System.Windows.Threading.Dispatcher ESRI.ArcGIS.Client.Tasks.TaskBase.get_Dispatcher()'.
   at ESRI.ArcGIS.Client.BAO.Tasks.AuthenticationTask.OnExecuteCompleted(AuthenticationEventArgs args)
   at ESRI.ArcGIS.Client.BAO.Tasks.AuthenticationTask.AuthenticationCompleted(Object sender, RequestEventArgs e)
   --- End of inner exception stack trace ---}
To avoid this error the best option is to use the Silverlight API DLLs which are version 1.2.0.177.
ESRI.ArcGIS.Client.dll
ESRI.ArcGIS.Client.Toolkit.dll
This was tested by migrating an old Visual Studio 2008 SP1 and Silverlight 3.0 Application to Visual Studio 2010 .NET Framework 4.0 and Silverlight 4.0.

Monday, November 22, 2010

How to write and read cookies from Silverlight ?

Here is the sample code to write and read cookies from Silverlight.

Make sure the DateTime.UtcNow is used.


private void SaveCookie(string key, string value)
{
// Expire in 30 days
DateTime expireDate = DateTime.UtcNow + TimeSpan.FromDays(30);
string newCookie = key + "=" + value + ";expires=" + expireDate.ToString("R");
HtmlPage.Document.SetProperty("cookie", newCookie);
}




private string ReadCookie(string key)
{
string[] cookies = HtmlPage.Document.Cookies.Split(';');
foreach (string cookie in cookies)
{
string[] keyValue = cookie.Split('=');
if (keyValue.Length == 2)
{
if (keyValue[0].ToString().Trim() == key.Trim())
return keyValue[1];
}
}
return null;
}

How to update Internet Explorer Status Bar from Silverlight ?

Here is the sample code which checks for Internet Explorer and updates the status bar to "Hello World".

string strAgent = HtmlPage.BrowserInformation.UserAgent;
if (strAgent.IndexOf("MSIE") > -1)
    HtmlPage.Window.SetProperty("status", "Hello World");

Wednesday, October 6, 2010

Convert Date and Time to proper format in Silverlight Datagrid or Map Tooltip

When you map Date Field to Silverlight 3 Datagrid Control or Tooltip control the full date and time value will appear. For example like 12/13/2010 12:00:00. Sometimes it is required to display only the Date value or only the time value.

Here are the steps to follow

1. In the .xaml file make sure the application namespace is refered properly like shown in this example.

xmlns:CustomControls="clr-namespace:SilverlightGISApp"

2. In the .xaml file add the converter class as a Grid resource. In this example the class CValueConverter is used.

<Grid.Resources>
<CustomControls:CValueConverter x:Name="MyToolTipConverter"></CustomControls:CValueConverter>

3. In case of datagrid use the following sample

<esriToolkit:FeatureDataGrid Grid.Row="0" Grid.Column="0" x:Name="DataGridControl" Width="210"
Map="{Binding ElementName=MapControl}" AutoGeneratingColumn="DataGridControl_AutoGeneratingColumn"
GraphicsLayer="{Binding ElementName=MapControl, Path=Layers.[5]}" CurrentCellChanged="DataGridControl_CurrentCellChanged" >
</esriToolkit:FeatureDataGrid>

4. In case of Tooltip use the following sample

<StackPanel Orientation="Horizontal">
  <TextBlock x:Name="LabelIncidentDate" Text="Incident Date: " FontWeight="Bold" Foreground="#FF0F274E" FontSize="10" VerticalAlignment="Center"/>
  <TextBlock x:Name="IncidentDate" Text="{Binding Converter={StaticResource MyToolTipConverter}, ConverterParameter=alm_date, Mode=OneWay}" HorizontalAlignment="Left"             VerticalAlignment="Center"  />
</StackPanel>


5. Note in DataGrid the "MyToolTipConverter" resource is not used. This is because it is handled programatically during the "Column Generating Event".

private void DataGridControl_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
DataGridTextColumn dataGridTextColumn = (DataGridTextColumn)e.Column;
if ((e.Column.Header.ToString().ToUpper() == IncidentDateColName.ToUpper()))
{
CValueConverter oDateConverter = new CValueConverter();
dataGridTextColumn.Binding.ConverterParameter = e.Column.Header.ToString();
dataGridTextColumn.Binding.Converter = oDateConverter;
}
if ((e.Column.Header.ToString().ToUpper() == IncidentTimeColName.ToUpper()))
{
e.Cancel = true;
}
if ((e.Column.Header.ToString().ToUpper() == FireIncidentsUniqueIDFieldName.ToUpper()))
{
e.Cancel = true;
}
}

6. Finally here is the custom class which will do the conversion task. Note down the signature of the “Convert” function. The required values will come in and the necessary logic can be implemented.
namespace SilverlightGISApp
{
    public class CValueConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (value is string)
            {
                char[] ToSplitDate = { '/' };
                char[] ToSplitTime = { ':' };
                string[] InStringDate = value.ToString().Split(ToSplitDate);
                string[] InStringTime = value.ToString().Split(ToSplitTime);
                int Month = System.Convert.ToInt16(InStringDate[0]);
                int Day = System.Convert.ToInt16(InStringDate[1]);
                int Year = System.Convert.ToInt16(InStringDate[2].Substring(0, 4));
                int Hour = System.Convert.ToInt16(InStringTime[0].Substring((InStringTime[0].Length - 2), 2));
                int Min = System.Convert.ToInt16(InStringTime[1]);
                int Sec = System.Convert.ToInt16(InStringTime[2].Substring(0, 2));
                string AMorPM = InStringTime[2].Substring((InStringTime[2].Length - 2), 2);
                if ((AMorPM == "PM") && (Hour != 12)) Hour = Hour + 12;
                DateTime date = new DateTime(Year, Month, Day, Hour, Min, Sec);
                string ToGoValue = "";
                if (parameter.ToString().ToUpper() == MainPage.IncidentDateColName.ToUpper()) ToGoValue = date.ToShortDateString();
                if (parameter.ToString().ToUpper() == MainPage.IncidentTimeColName.ToUpper()) ToGoValue = date.ToShortTimeString();
                return ToGoValue;
            }
            else if ((value is System.Collections.Generic.Dictionary<string, object>) && (MainPage.IncidentTypeColName.Trim().ToUpper() != parameter.ToString().Trim().ToUpper()))
            {
                System.Collections.Generic.Dictionary<string, object> theDictionary = value as System.Collections.Generic.Dictionary<string, object>;
                string theDateTimeValue = theDictionary[parameter as string].ToString();

                char[] ToSplitDate = { '/' };
                char[] ToSplitTime = { ':' };
                string[] InStringDate = theDateTimeValue.ToString().Split(ToSplitDate);
                string[] InStringTime = theDateTimeValue.ToString().Split(ToSplitTime);
                int Month = System.Convert.ToInt16(InStringDate[0]);
                int Day = System.Convert.ToInt16(InStringDate[1]);
                int Year = System.Convert.ToInt16(InStringDate[2].Substring(0, 4));
                int Hour = System.Convert.ToInt16(InStringTime[0].Substring((InStringTime[0].Length - 2), 2));
                int Min = System.Convert.ToInt16(InStringTime[1]);
                int Sec = System.Convert.ToInt16(InStringTime[2].Substring(0, 2));
                string AMorPM = InStringTime[2].Substring((InStringTime[2].Length - 2), 2);
                if ((AMorPM == "PM") && (Hour != 12)) Hour = Hour + 12;
                DateTime date = new DateTime(Year, Month, Day, Hour, Min, Sec);
                string ToGoValue = "";
                if (parameter.ToString().ToUpper() == MainPage.IncidentDateColName.ToUpper()) ToGoValue = date.ToShortDateString();
                if (parameter.ToString().ToUpper() == MainPage.IncidentTimeColName.ToUpper()) ToGoValue = date.ToShortTimeString();
                return ToGoValue;
            }
            else if ((value is System.Collections.Generic.Dictionary<string, object>) && (MainPage.IncidentTypeColName.Trim().ToUpper() == parameter.ToString().Trim().ToUpper()))
            {
                System.Collections.Generic.Dictionary<string, object> theDictionary = value as System.Collections.Generic.Dictionary<string, object>;
                string thetypeValue = theDictionary[parameter as string].ToString();

                string ToGoValue = "";
                if (thetypeValue == "100") ToGoValue = "E.M.S";
                if (thetypeValue == "311") ToGoValue = "Fire";
                if (thetypeValue == "324") ToGoValue = "Other";
                if (thetypeValue.Trim() == "") ToGoValue = "Other";
                return ToGoValue;
            }
            else
            {
                string ToGoValue = "";
                return ToGoValue;
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            string strValue = value.ToString();
            DateTime resultDateTime;
            if (DateTime.TryParse(strValue, out resultDateTime))
            {
                return resultDateTime;
            }
            return value;
        }
    }
}


Sunday, September 19, 2010

Latitude and Longitude values for Address

Use this tool to get latitude and longitude values for one or multiple address.

Click here to access the tool.

Saturday, September 11, 2010

MP3 Downloader

Sometimes you may see many mp3 files to download from the same page. You have to click each link and then save it to your computer.

Here is a simple tool which can help you under such situations.

Download the MP3Downloader ZIP file and install the program on your computer.

Double-click the short-cut installed on your machine.

You will see a dialog box like this.


Enter the URL from which you want to download MP3 files and click Extract MP3 button.

All the MP3 Links will be listed. Click on "Download MP3" button and all the files will be downloaded to your C:\Temp\ folder.

Have fun !

Draggable Border in Silverlight

Sometimes it may be required to have draggable borders in Silverlight application.

In the XAML file create the definition for the Border.

Here is the XAML definition for Border.

==============================================

<!—Border Welcome -->
<Border x:Name="BorderWelcome" BorderBrush="Gray" BorderThickness="5" Width="180" Height="100" Background="Silver" VerticalAlignment="Top" HorizontalAlignment="Right" Margin="0,100,10,0" Visibility="Collapsed" CornerRadius="10" >
<Grid x:Name="GridWelcome" Height="90" Width="170">
<StackPanel>
</StackPanel>
</Grid>
</Border>

==============================================

In the C sharp code add this new class (BorderDragDrop) to the project.

==============================================
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace SilverlightGISApp
{
public class BorderDragDrop
{
Border border;
bool IsmouseDown = false;
TranslateTransform TTObject = new TranslateTransform();
Point originalWindowPoint;
bool getOrigWindowPosition = true;
private BorderDragDrop() { }
/// <summary>
/// Allow a Border to be dragged.
/// </summary>
public static void Attach(Border inborder)
{
BorderDragDrop bdd = new BorderDragDrop { border = inborder };
FrameworkElement theFrameworkElement = inborder as FrameworkElement;
theFrameworkElement.MouseLeftButtonDown += bdd.border_MouseLeftButtonDown ;
theFrameworkElement.MouseLeftButtonUp += bdd.border_MouseLeftButtonUp ;
theFrameworkElement.MouseMove += bdd.border_MouseMove ;
}

private void border_MouseMove(object sender, MouseEventArgs e)
{
FrameworkElement b = sender as FrameworkElement;
Point currntPoint = e.GetPosition(null);
if (IsmouseDown)
{
b.RenderTransform = TTObject;
TTObject.X = currntPoint.X - originalWindowPoint.X;
TTObject.Y = currntPoint.Y - originalWindowPoint.Y;
}
}

private void border_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
FrameworkElement b = sender as FrameworkElement;
b.ReleaseMouseCapture();
IsmouseDown = false;
border.Cursor = Cursors.Arrow;
}

private void border_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
object origMouseDownSource = e.OriginalSource;
if (origMouseDownSource.GetType() != typeof(Border)) return;
FrameworkElement b = sender as FrameworkElement;
IsmouseDown = true;
if (getOrigWindowPosition == true)
{
originalWindowPoint = e.GetPosition(null);
getOrigWindowPosition = false;
}
b.CaptureMouse();
border.Cursor = Cursors.Hand;
}
}
}
==============================================

During the InitializeAppSettings() function call add the following line of code.

BorderDragDrop.Attach(BorderWelcome);

Now the border becomes draggable.

Monday, September 6, 2010

Buffering in Google Maps

Have you ever wondered what are the landmarks within 1000 feet of your home ?
Using this Google Buffering Tool you can analyze and check.

Here is how it looks.

Sunday, September 5, 2010

To call a Javascript from a class which is not derived from Web Page in ESRI ArcGIS Server ADF

Problem :

To call a Javascript function from a C Sharp class in ArcGIS Server ADF Application. 

Possible Solutions :

Use a callbackresult and add it to the Map Control as shown below.


public class DownloadMap : IMapServerToolAction
{
#region IMapServerToolAction Members

void IMapServerToolAction.ServerAction(ESRI.ArcGIS.ADF.Web.UI.WebControls.ToolEventArgs args)
{
Map map = (Map)args.Control;
MapCircleEventArgs theMapCircleEventArgs = (MapCircleEventArgs)args;
map.Page.Session["CircleCenterX"] = theMapCircleEventArgs.MapCenter.X.ToString();
map.Page.Session["CircleCenterY"] = theMapCircleEventArgs.MapCenter.Y.ToString();
map.Page.Session["CircleRadius"] = theMapCircleEventArgs.MapRadius.ToString();
StringBuilder sb = new StringBuilder();
sb.Append("function owin() { window.open('DownloadPage.aspx'); } owin() ;");
ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult theCallbackResult = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateJavaScript(sb.ToString());
map.CallbackResults.Add(theCallbackResult);
}
#endregion
}

Visual Studio 2008 - Namespace was not recognised

Problem :

The Namespace found in one of the C sharp file was not at all recognized.

Possible Solution :

Check the property of the file of the C sharp file. It should say Compile instead of Content.

System.Runtime.Serialization.Json Namespace Issue

Problem :

The .Json namespace was missing and giving compilation error.

Possible Solution :

The System.ServiceModel.Web should be used along with System.Runtime.Serialization. Then Json will be recognized.

All Blogs so far ...