Select to view content in your preferred language

Adding Hyperlink Support to the FeatureDataGrid in Silverlight

1731
1
08-13-2010 07:14 AM
JoshuaCorcoran
Emerging Contributor
All,

I figured it was time I make my first post this forum and finally give some advice rather than ask for it. So I came across a problem yesterday where I needed to add Hyperlink Support to the FeatureDataGrid which by default does not exist. Here are the steps to add support. This fix may work for 2.0\Silverlight 4 but I have not tested it and make no guarentees.

1. Go to http://esrisilverlight.codeplex.com/SourceControl/list/changesets and download the sourcecode for the esri toolkit v1.2.

2. Unzip and open the silverlight project in Visual Studio.

3. Under the project folder 'FeatureDataGrid'.

4. Open FeatureDataGrid.cs

5. Declare 2 private variables:
    - private static bool hasFixedColumns = false;
    - private static List<string> urlColumns = new List<string>();

6. Declare 3 Private Methods:

private DataTemplate GetColumnDataTemplate(string BindingProperty)
{
   //Local Variable Declaration
   DataTemplate dt = null;
   string controlTemplate = string.Empty;

   controlTemplate = @"<DataTemplate xmlns=""http://schemas.microsoft.com/winfx/2006/presentation""
                                     xmlns=""http://schemas.microsoft.com/winfx/2006/xaml"">
                                     <HyperlinkButton Content=""{Binding " + BindingProperty + @"}"" + NavigateUri=""{Binding " + BindingProperty + @"}"" Foreground=""Blue"" TargetName=""_blank""/>
         </DataTemplate";
   dt = XamlReader.Load(controlTemplate) as DataTemplate;
   return dt;
}

private bool ExistsInList(string ColumnName)
{
  foreach(string Item in urlColumns)
  {
    if (Item == ColumnName) { return true; }
  }

  return false; 
}

private static bool IsURL(object Item)
{
  string str = Item != null ? Item.toStrig() : string.Empty;

  if (!string.IsNullOrEmpty(str))
  {
    str = str.ToLower();

    if (str.Contains("http") || str.Contains("https") || str.Contains("\\\\"))
    {
return true;
    }
  }

  return false;
}


7. Under the constructors Region expand the default constructor and add the following code:

base.LoadingRow += (sender, e) =>
{
   if (!hasFixedColumns)
   {
      FeatureDataGrid fdg = sender as FeatureDataGrid;
      Dictionary<int,DataGridTemplateColumn> newColumns = new Dictionary<int,DataGridTemplateColumn>();

      foreach(DataGridColumn Item in fdg.Columns)
      {
if (Item.Header != null && this.ExistsinList(Item.Header.ToString())
{
   DataGridTemplateColumn newColumn = new DataGridTemplateColumn();
   newColumn.CellTemplate = this.GetColumnDataTemplate(Item.Header.ToString());
   newColumn.Header = Item.Header;

   newColumns.Add(Item.DisplayIndex, newColumn);
}
      }

      if (newColumns.Count > 0)
      {
foreach(KeyValuePair<int,DataGridTemplateColumn> Item in newColumns)
{
   fdg.Columns.RemoveAt(Item.Key);
   fdg.Columns.Insert(Item.Key, Item.Value);
}
      }
   }
};

8. Under Dependency property region expand OnGraphicLayerPropertyChanged method.

9. Directly under the comment '//Populating FeatureDataGrid's ItemsSource' add the following code:

urlColumns.Clear();
hasFixedColumns = false;

Graphic firstGraphic = newValue.Graphics.FirstOrDefault<Graphic>();

foreach (KeyValuePair<string, object> Attrib in firstGraphic.Attributes)
{
  if (Attrib.Value != null && IsURL(Attrib.Value.toString())
  {
     urlColumns.Add(Attrib.Key);
  }
}

10. Recompile the code and your golden. Hope this helps.

V/R,

Joshua A Corcoran
Sr. Geospatial Developer
L-3 Communciations.
corcornj@gmail.com
0 Kudos
1 Reply
AliMirzabeigi
Emerging Contributor
Joshua,

Very cool! Thanks a lot for sharing this information.
Just as an alternate way of doing this you could also set the AutoGenerateColumns property of FeatureDataGrid to false and define columns data templates inside of your XAML. For example in the following code snippet the associated layer has two attributes: type and description in which the latter includes URIs for navigation.
You would also need to add a XML namespace as
xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"


<esri:FeatureDataGrid x:Name="MyFeatureDataGrid" Height="240" VerticalAlignment="Bottom" AutoGenerateColumns="False" 
         Map="{Binding ElementName=MyMap}" GraphicsLayer="{Binding Layers[1], ElementName=MyMap}">
   <esri:FeatureDataGrid.Columns>
    <data:DataGridTextColumn Binding="{Binding type}" Header="Type" />
    <data:DataGridTemplateColumn Header="Description">
     <data:DataGridTemplateColumn.CellTemplate>
      <DataTemplate>
       <HyperlinkButton Content="{Binding description}" NavigateUri="{Binding description}" TargetName="_blank" />
      </DataTemplate>
     </data:DataGridTemplateColumn.CellTemplate>
    </data:DataGridTemplateColumn>
   </esri:FeatureDataGrid.Columns>
  </esri:FeatureDataGrid>
0 Kudos