Select to view content in your preferred language

Field Hyperlink

624
4
Jump to solution
05-29-2012 11:13 AM
TanyaOwens
Frequent Contributor
I have modified the sample identify code http://help.arcgis.com/en/webapi/silverlight/samples/start.htm#Identify to display the identify results from 3 layers into 3 different datagrids. One of the fields in each data grid has data that needs to be a hyperlink. Currently I am using this code (see below) to get one of the data grids to display a field as a hyperlink but I am unsure how to modify it to work for all 3 data grids. Any thoughts - I am willing to try a different code if anyone has one.
        //Hyperlink         private void IdentifyDetailsDataGrid_LoadingRow(object sender, DataGridRowEventArgs e)         {             try             {                  string s = e.Row.DataContext.ToString();                 //Check for the field name "Website".                 if (s.Contains("Website"))                 {                     string[] sSplit = s.Split(',');                     string[] link = sSplit[1].Split(']');                      DataGridColumn column = this.IdentifyDetailsDataGrid.Columns[1];                     FrameworkElement fe = column.GetCellContent(e.Row);                     FrameworkElement result = GetParent(fe, typeof(DataGridCell));                     if (result != null)                     {                         DataGridCell cell = (DataGridCell)result;                          //Set the URL to empty sring if found a null value.                         //if (String.IsNullOrEmpty(link[0].Trim()))                         if (link[0].Trim() == "Null" || link[0] == null)                             link[0] = String.Empty;                         cell.Content = new URLField() { url = link[0] };                            DataTemplate dt = this.Resources["HyperlinkButtonTemplate"] as DataTemplate;                         cell.ContentTemplate = dt;                       }                 }              }             catch             {             }          }          private FrameworkElement GetParent(FrameworkElement child, Type targetType)         {             object parent = child.Parent;             if (parent != null)             {                 if (parent.GetType() == targetType)                 {                     return (FrameworkElement)parent;                 }                 else                 {                     return GetParent((FrameworkElement)parent, targetType);                 }             }             return null;         }     }      public class URLField     {         public string url { get; set; }     }


The following is the code that I am using to separate out my fields and layers into separate data grids:

        public void ShowFeatures(List<IdentifyResult> results)         {             _dataItems = new List<DataItem>();              if (results != null && results.Count > 0)             {                                  foreach (IdentifyResult result in results)                 {                      Graphic feature = result.Feature;                     string title = result.Value.ToString() + " (" + result.LayerName + ")";                     _dataItems.Add(new DataItem()                      {                          Title = title,                         Data = feature.Attributes                      });                                          var fieldsToDisplay = new List<string>() { "School Name", "Address", "Zip", "Phone", "Website", "School District" };                     var attributesToDisplay = new Dictionary<string, object>();                     foreach (var item in feature.Attributes)                         if (fieldsToDisplay.Contains(item.Key))                             attributesToDisplay[item.Key] = item.Value;                                           if (result.LayerId == 4)                         IdentifyDetailsDataGrid.ItemsSource = feature.Attributes;                         IdentifyDetailsDataGrid.ItemsSource = attributesToDisplay;                     if (result.LayerId == 9)                         IdentifyDetailsDataGrid2.ItemsSource = feature.Attributes;                         IdentifyDetailsDataGrid2.ItemsSource = attributesToDisplay;                       if (result.LayerId == 14)                         IdentifyDetailsDataGrid3.ItemsSource = feature.Attributes;                         IdentifyDetailsDataGrid3.ItemsSource = attributesToDisplay;                  }


Thanks!
0 Kudos
1 Solution

Accepted Solutions
TanyaOwens
Frequent Contributor
Thanks for trying. I only a couple weeks in to using silverlight and I feel a bit lost. I did post this question to the silverlight forum and got a great answer. Check it out http://forums.silverlight.net/p/256391/640787.aspx/1?p=True&t=634741473008894741

Thanks to Shi Ding, my code now works in all three data grids. In addition to the link, I will paste the answer Shi Ding provided below:

Based on your code, i see that in this method, there are two hard coded parts. So change them to dynamical passed in parameter can make it re-usable.
One is checking for a particular field through field name. Another one is IdentifyDetailsDataGrid.
    private void IdentifyDetailsDataGrid_LoadingRow(object sender, DataGridRowEventArgs e)
        {
             DataGrid dataGrid  = sender as DataGrid;

           //Add some code to switch dataGrid.Name and give different field name
           string fieldName;
           Switch (dataGrid.Name)
           case("XXXXX")
                   fieldName = "XXXX";
           case ("XXXX")
                   fieldName = "XXXX";
           .......
            try
            {

                string s = e.Row.DataContext.ToString();
                //Check for the field name "Website".
                if (s.Contains(fieldName)) //use fieldName variable instead
                {
                    string[] sSplit = s.Split(',');
                    string[] link = sSplit[1].Split(']');

                    DataGridColumn column = dataGrid.Columns[1]; // use dataGrid which is dynamically cast from event sender.
                    FrameworkElement fe = column.GetCellContent(e.Row);
                    FrameworkElement result = GetParent(fe, typeof(DataGridCell));
                    if (result != null)
                    {
                        DataGridCell cell = (DataGridCell)result;

                        //Set the URL to empty sring if found a null value.
                        //if (String.IsNullOrEmpty(link[0].Trim()))
                        if (link[0].Trim() == "Null" || link[0] == null)
                            link[0] = String.Empty;
                        cell.Content = new URLField() { url = link[0] };
 
                        DataTemplate dt = this.Resources["HyperlinkButtonTemplate"] as DataTemplate;
                        cell.ContentTemplate = dt;


                    }
Best Regards,

View solution in original post

0 Kudos
4 Replies
JaredWhite
Regular Contributor
Try replacing your hyperlink code with this

        private void IdentifyDetailsDataGrid_LoadingRow(object sender, DataGridRowEventArgs e)
        {
            try
            {

                string s = e.Row.DataContext.ToString();
                if (s.Contains("http"))
                {
                    string[] sSplit = s.Split(',');
                    string[] link = sSplit[1].Split(']');

                    DataGridColumn column = this.IdentifyDetailsDataGrid.Columns[1];
                    FrameworkElement fe = column.GetCellContent(e.Row);
                    FrameworkElement result = GetParent(fe, typeof(DataGridCell));
                    if (result != null)
                    {
                        DataGridCell cell = (DataGridCell)result;
                        if (link[0].Trim() == "Null" || link[0] == null)
                            link[0] = String.Empty;
                        cell.Content = new URLField() { url = link[0] };
                      DataTemplate dt = this.Resources["HyperlinkButtonTemplate"] as DataTemplate;
                        cell.ContentTemplate = dt;
                    }
                }
            }
            catch
            {
            }
        }


        private FrameworkElement GetParent(FrameworkElement child, Type targetType)
        {
            object parent = child.Parent;
            if (parent != null)
            {
                if (parent.GetType() == targetType)
                {
                    return (FrameworkElement)parent;
                }
                else
                {
                    return GetParent((FrameworkElement)parent, targetType);
                }
            }
            return null;
        }
    }

    public class URLField
    {
        public string url { get; set; }
    }


And make sure you put this :

      <DataTemplate x:Key="HyperlinkButtonTemplate">
            <HyperlinkButton x:Name="hl" Margin="5" TargetName="_blank"
                             Content="{Binding url}" NavigateUri="{Binding url}"/>
        </DataTemplate>


in your <UserControl.Resources> at the beginning of your mainpage XAML
0 Kudos
TanyaOwens
Frequent Contributor
Thanks. This code is similar to the one I was using. Both work great for creating a hyperlink in a single data grid but I do not know how to create a loop in the code to make it do the hyperlink for each data grid. I have a separate data grid for each layer that I am identifying. I have tried you copying the code and setting it up for each data grid but it just gives me all kind of errors. Below is my xaml code for the three data grids. My original post shows how I have the identify tool looping to send the data for each layer to the corresponding data grid.

                <StackPanel x:Name="IdentifyResultsStackPanel" 
                            Margin="15,30,15,10" 
                            Visibility="Collapsed">

                    <TextBlock Text="ELEMENTARY SCHOOL ATTENDANCE AREA:" 
                               Foreground="White" 
                               FontSize="14" 
                               FontStyle="Italic" 
                               Margin="0,0,0,5" />
                    
                    <slData:DataGrid x:Name="IdentifyDetailsDataGrid" 
                                     AutoGenerateColumns="False"
                                     LoadingRow="IdentifyDetailsDataGrid_LoadingRow"
                                     HeadersVisibility="None" >
                        <slData:DataGrid.Columns>
                                <slData:DataGridTextColumn Binding="{Binding Path=Key}" FontWeight="Bold"/>
                                <slData:DataGridTextColumn Binding="{Binding Path=Value}"/>
                                
                        </slData:DataGrid.Columns>
                        </slData:DataGrid>
                    
                    <TextBlock Text="MIDDLE SCHOOL ATTENDANCE AREA:" 
                               Foreground="White" 
                               FontSize="14" 
                               FontStyle="Italic" 
                               Margin="0,0,0,5" />
                        <slData:DataGrid x:Name="IdentifyDetailsDataGrid2" 
                                         AutoGenerateColumns="False"
                                         LoadingRow="IdentifyDetailsDataGrid_LoadingRow"
                                         HeadersVisibility="None" >
                            <slData:DataGrid.Columns>
                                <slData:DataGridTextColumn Binding="{Binding Path=Key}" FontWeight="Bold"/>
                                <slData:DataGridTextColumn Binding="{Binding Path=Value}"/>
                            </slData:DataGrid.Columns>
                        </slData:DataGrid>
                    
                    <TextBlock Text="HIGH SCHOOL ATTENDANCE AREA:" 
                               Foreground="White" 
                               FontSize="14" 
                               FontStyle="Italic" 
                               Margin="0,0,0,5" />
                    <slData:DataGrid x:Name="IdentifyDetailsDataGrid3" 
                                     AutoGenerateColumns="False"
                                     LoadingRow="IdentifyDetailsDataGrid_LoadingRow"
                                     HeadersVisibility="None" >
                        <slData:DataGrid.Columns>
                            <slData:DataGridTextColumn Binding="{Binding Path=Key}" FontWeight="Bold"/>
                            <slData:DataGridTextColumn Binding="{Binding Path=Value}"/>
                        </slData:DataGrid.Columns>
                    </slData:DataGrid>
                </StackPanel>
0 Kudos
JaredWhite
Regular Contributor
You need to write a string in the LoadingRow capture URL action to affect not only IdentifyDetailsDataGrid but IdentifyDetailsDataGrid1 and IdentifyDetailsDataGrid2 as well, I wish i could write it for you but I just started learning C# a handful of weeks ago.

     private void IdentifyDetailsDataGrid_LoadingRow(object sender, DataGridRowEventArgs e)
        {
            try
            {

                string s = e.Row.DataContext.ToString();
                if (s.Contains("http"))
                {
                    string[] sSplit = s.Split(',');
                    string[] link = sSplit[1].Split(']');

                      //Begin problem code
                    DataGridColumn column = this.IdentifyDetailsDataGrid.Columns[1];
                       //You need to write something like 
                       //DataGridColumn column = this.string
                       //{ foreach DataGrid.IdentifyDetailsDataGrid
                       //              DataGrid.IdentifyDetailsDataGrid1
                       //              DataGrid.IdentifyDetailsDataGrid2
                       // }

                    FrameworkElement fe = column.GetCellContent(e.Row);
                    FrameworkElement result = GetParent(fe, typeof(DataGridCell));
                    if (result != null)
                    {
                        DataGridCell cell = (DataGridCell)result;
                        if (link[0].Trim() == "Null" || link[0] == null)
                            link[0] = String.Empty;
                        cell.Content = new URLField() { url = link[0] };
                      DataTemplate dt = this.Resources["HyperlinkButtonTemplate"] as DataTemplate;
                        cell.ContentTemplate = dt;
                    }
                }
            }
            catch
            {
            }
        }


What I've written won't come anywhere close to working, but maybe it'll help you if you're more familiar with the language, or maybe one of the gurus can chime in with how the string should be written.

But, for now you can just add this below your first LoadingRow URL Capture action

 private void IdentifyDetailsDataGrid_LoadingRow2(object sender, DataGridRowEventArgs e)
        {
            try
            {

                string s = e.Row.DataContext.ToString();
                if (s.Contains("http"))
                {
                    string[] sSplit = s.Split(',');
                    string[] link = sSplit[1].Split(']');

                    DataGridColumn column = this.IdentifyDetailsDataGrid2.Columns[1];
                    FrameworkElement fe = column.GetCellContent(e.Row);
                    FrameworkElement result = GetParent(fe, typeof(DataGridCell));
                    if (result != null)
                    {
                        DataGridCell cell = (DataGridCell)result;
                        if (link[0].Trim() == "Null" || link[0] == null)
                            link[0] = String.Empty;
                        cell.Content = new URLField() { url = link[0] };
                      DataTemplate dt = this.Resources["HyperlinkButtonTemplate"] as DataTemplate;
                        cell.ContentTemplate = dt;
                    }
                }
            }
            catch
            {
            }
        }

 private void IdentifyDetailsDataGrid_LoadingRow3(object sender, DataGridRowEventArgs e)
        {
            try
            {

                string s = e.Row.DataContext.ToString();
                if (s.Contains("http"))
                {
                    string[] sSplit = s.Split(',');
                    string[] link = sSplit[1].Split(']');

                    DataGridColumn column = this.IdentifyDetailsDataGrid3.Columns[1];
                    FrameworkElement fe = column.GetCellContent(e.Row);
                    FrameworkElement result = GetParent(fe, typeof(DataGridCell));
                    if (result != null)
                    {
                        DataGridCell cell = (DataGridCell)result;
                        if (link[0].Trim() == "Null" || link[0] == null)
                            link[0] = String.Empty;
                        cell.Content = new URLField() { url = link[0] };
                      DataTemplate dt = this.Resources["HyperlinkButtonTemplate"] as DataTemplate;
                        cell.ContentTemplate = dt;
                    }
                }
            }
            catch
            {
            }
        }



and change your xaml lines

 <slData:DataGrid x:Name="IdentifyDetailsDataGrid2" 
                                         AutoGenerateColumns="False"
                                         LoadingRow="IdentifyDetailsDataGrid_LoadingRow"
                                         HeadersVisibility="None" >
and

                    <slData:DataGrid x:Name="IdentifyDetailsDataGrid3" 
                                     AutoGenerateColumns="False"
                                     LoadingRow="IdentifyDetailsDataGrid_LoadingRow"
                                     HeadersVisibility="None" >



to

<slData:DataGrid x:Name="IdentifyDetailsDataGrid2" 
                                         AutoGenerateColumns="False"
                                         LoadingRow="IdentifyDetailsDataGrid_LoadingRow2"
                                         HeadersVisibility="None" >

and

                    <slData:DataGrid x:Name="IdentifyDetailsDataGrid3" 
                                     AutoGenerateColumns="False"
                                     LoadingRow="IdentifyDetailsDataGrid_LoadingRow3"
                                     HeadersVisibility="None" >



It isn't pretty, but it should work.
0 Kudos
TanyaOwens
Frequent Contributor
Thanks for trying. I only a couple weeks in to using silverlight and I feel a bit lost. I did post this question to the silverlight forum and got a great answer. Check it out http://forums.silverlight.net/p/256391/640787.aspx/1?p=True&t=634741473008894741

Thanks to Shi Ding, my code now works in all three data grids. In addition to the link, I will paste the answer Shi Ding provided below:

Based on your code, i see that in this method, there are two hard coded parts. So change them to dynamical passed in parameter can make it re-usable.
One is checking for a particular field through field name. Another one is IdentifyDetailsDataGrid.
    private void IdentifyDetailsDataGrid_LoadingRow(object sender, DataGridRowEventArgs e)
        {
             DataGrid dataGrid  = sender as DataGrid;

           //Add some code to switch dataGrid.Name and give different field name
           string fieldName;
           Switch (dataGrid.Name)
           case("XXXXX")
                   fieldName = "XXXX";
           case ("XXXX")
                   fieldName = "XXXX";
           .......
            try
            {

                string s = e.Row.DataContext.ToString();
                //Check for the field name "Website".
                if (s.Contains(fieldName)) //use fieldName variable instead
                {
                    string[] sSplit = s.Split(',');
                    string[] link = sSplit[1].Split(']');

                    DataGridColumn column = dataGrid.Columns[1]; // use dataGrid which is dynamically cast from event sender.
                    FrameworkElement fe = column.GetCellContent(e.Row);
                    FrameworkElement result = GetParent(fe, typeof(DataGridCell));
                    if (result != null)
                    {
                        DataGridCell cell = (DataGridCell)result;

                        //Set the URL to empty sring if found a null value.
                        //if (String.IsNullOrEmpty(link[0].Trim()))
                        if (link[0].Trim() == "Null" || link[0] == null)
                            link[0] = String.Empty;
                        cell.Content = new URLField() { url = link[0] };
 
                        DataTemplate dt = this.Resources["HyperlinkButtonTemplate"] as DataTemplate;
                        cell.ContentTemplate = dt;


                    }
Best Regards,
0 Kudos