Select to view content in your preferred language

Binding two way on a relate

697
1
Jump to solution
11-08-2012 01:32 PM
NathalieNeagle
Regular Contributor
I have a related table setup like the example, I also have a feature data grid setup that works with my basic spatial and attibute selection and I noticed when I click on a APN (item) in the tree - it also selects or highlights the layer in FDG. I want to two way bind my tree so when I select a item in my FDG it selects the item in my tree. Can you help me with this?

Resources - XAML (MY RESOURCE for my tree)
 <!-- RELATED LINK RESOURCE-->
            <common:HierarchicalDataTemplate x:Key="TreeViewItemTemplate">
               <StackPanel Orientation="Horizontal" Margin="0">
                    <!--<Ellipse Fill="Transparent" Height="6" Width="6" StrokeThickness="2" Stroke="Black" Margin="0,0,10,0"/>-->
                 <TextBlock Text="APN:  " HorizontalAlignment="Left" FontSize="10" Margin="0"/>
                <TextBlock x:Name="TextBlockRelate" Text="{Binding Attributes[APN], Mode=TwoWay}" HorizontalAlignment="Left" FontSize="10"/>
               
                </StackPanel>
            </common:HierarchicalDataTemplate>
            <!--END RELATED LINK RESOURCE-->



XAML MY TREE AND FDG FOR RELATED RECORDS
  <userControls:DraggableWindow x:Name="RelateResultsDisplay"  IsOpen="False" 
        VerticalAlignment="Bottom" HorizontalAlignment="Right" 
               Margin="15" Effect="{StaticResource dropShadow}" Title="RELATED WORK RESULTS TABLE" Background="Black">
              <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="Auto" Height="Auto" >
                <Border Effect="{StaticResource miniDropShadow}" Style="{StaticResource RibbonElementBorder}" Padding="15" Margin="10">
                    <Grid x:Name="RelatedRowsGrid" HorizontalAlignment="Right"
                     VerticalAlignment="Top" MinHeight="170" Width="Auto">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="140" />
                            <ColumnDefinition MaxWidth="600" />
                        </Grid.ColumnDefinitions>
                         <StackPanel Orientation="Vertical" Margin="1,-5,1,5">
                          <TextBlock Margin="1,0,5,1" TextWrapping="Wrap" Grid.Column="0" 
                           Text="Click to see relates: " 
                           FontSize="10" FontFamily="Arial" Foreground="#FFFFFFFF" />

                           <basics:TreeView x:Name="SelectedWellsTreeView" MaxHeight="180"  Grid.Column="0"  Margin="1"
                                 ItemsSource="{Binding}" BorderBrush="Gray" BorderThickness=".5"
                  SelectedItemChanged="SelectedWellsTreeView_SelectedItemChanged" 
                                 ItemTemplate="{StaticResource TreeViewItemTemplate}"
                             />
                           </StackPanel>
                        <esriWidgets:FeatureDataGrid Grid.Column="1" Grid.Row="1" x:Name="MyFDG" Height="180" 
                                Style="{StaticResource FeatureDataGridRelateStyle1}" MouseLeftButtonUp="MyFDG_MouseLeftButtonUp"
                                                  
                                />


                    </Grid>
                </Border>

            </Grid>
        </userControls:DraggableWindow>



MY XAML FOR MY SELECTION FDG - THE ONE I WANT TO SELECT A ROW/RECORD HERE AND HAVE IT SELECT MY CORRESPONDING TREE ITEM AND SHOW THE RELATED RECORDS


 <userControls:DraggableWindow x:Name="ResultsDisplay"  IsOpen="True" 
        VerticalAlignment="Bottom" HorizontalAlignment="Right" 
               Margin="15" Effect="{StaticResource dropShadow}" Title="RESULTS TABLE" Background="Black">

            <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="Auto" Height="Auto" >
                  <Border Effect="{StaticResource miniDropShadow}" Style="{StaticResource RibbonElementBorder}" Padding="15" Margin="10">

                    

                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="15" />
                                <RowDefinition Height="*" />
                            </Grid.RowDefinitions>
                            <TextBlock x:Name="DataDisplayTitle" Text="Search Results" FontSize="9" Grid.Row="0" FontWeight="Bold" FontFamily="Arial" Foreground="#FFFFFFFF" />
                              <esriWidgets:FeatureDataGrid Grid.Row="1" x:Name="QueryDetailsDataGrid" Height="170" 
                                      Map="{Binding ElementName=Map}" 
                                      GraphicsLayer="{Binding Layers[MySelectionGraphicsLayer], ElementName=Map}" Style="{StaticResource FeatureDataGridStyle1}"  MouseLeftButtonUp="QueryDetailsDataGrid_MouseLeftButtonUp" SelectionChanged="QueryDetailsDataGrid_SelectionChanged"
                                       />

                        </Grid>

                 

                    </Border>
               
            </Grid>
        </userControls:DraggableWindow>
        



CODE BEHIND


   private void SelectedWellsTreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
            if (e.OldValue != null)
            {
                Graphic g = e.OldValue as Graphic;
                g.UnSelect();
                g.SetZIndex(0);
            }

            if (e.NewValue != null)
            {
                Graphic g = e.NewValue as Graphic;
                g.Select();
                g.SetZIndex(1);


         

                //OBJECTID, PARCELID, X_COORD, Y_COORD, APN, ADDRNMBR, ADDRNAME, GEN_PLAN
                //Relationship query
                RelationshipParameter relationshipParameters = new RelationshipParameter()
                {
                                 
                    ObjectIds = new int[] { Convert.ToInt32(g.Attributes[SelectedWellsTreeView.Tag as string]) },
                    OutFields = new string[] { "*" },
                    RelationshipId = 0,
                    OutSpatialReference = Map.SpatialReference,
               
                    
                 };
                queryTask.ExecuteRelationshipQueryAsync(relationshipParameters);

                relateIDstring = g.Attributes["APN"].ToString();

            //    MessageBox.Show(g.Attributes["OWN_ADDR1"].ToString());


               // MyFeatureDataForm.GraphicSource = g;

            }
        }

        void QueryTask_ExecuteRelationshipQueryCompleted(object sender, RelationshipEventArgs e)
        {
            //  This line gets you the all features returned from the Relationship Query
            // IEnumerable<Graphic> graphics = e.Result.RelatedRecordsGroup.First().Value;

            RelationshipResult pr = e.Result;
            if (pr.RelatedRecordsGroup.Count == 0)
            {
                l.Where = "1=0"; //remember _featureLayer is l

                //   RelatedRowsDataGrid.ItemsSource = null;
            }
            else
            {
                foreach (var pair in pr.RelatedRecordsGroup)
                {
                    IEnumerable<Graphic> graphics = e.Result.RelatedRecordsGroup.First().Value;

                    //  RelatedRowsDataGrid.ItemsSource = pair.Value;
                    //   MyFDG.ItemsSource = pair.Value;
                    //  MyFDG.ItemsSource = pair.Value.Select(graphic => graphic.Attributes);
                    //    }

                    //}

                    // There are two ways to filter either using Where clause or using the ObjectIDs property
                    // before you set the Where clause to return all records 1=1 I think
                    // Here instead lets use the ObjectIDs approach, first get rid of the old Where 

                    l.Where = null; //remember _featureLayer is l

                    //ObjectIDs takes an int[] and with a little Linq we can get that array
                    // I am assumning you have included OBJECTID in your outfields when you defined the query

                    int[] objectIds = graphics.Select(g => (int)g.Attributes["OBJECTID_1"]).ToArray();

                    //now set the ObjectIDs on our FeatureLayer

                    l.ObjectIDs = objectIds;

                }

            }

            //Update the FeatureLayer to 'redraw' the new filtered set of Features

            l.Update();

            //And I hope this worked.  you could rebind the layer to the grid to make sure all is good
            MyFDG.GraphicsLayer = l;

            MyFeatureDataForm.FeatureLayer = l;
       

           // MyFDG.Resources["SeeRelateButton"].Visibility = Visibility.Visible;

         }
       #endregion




UNTIMELY I WOULD LOVE TO JUST REMOVE THE TREE VIEW LIST AND JUST USE MY FDG (2nd one name QueryDetailsDataGrid) because right now a user does a selection it populates the QueryDetailsDataGrid and then she/he opens the related tree and selects the item to populate and see the related records. I would rather just skip over the tree list and just have the user select one record in the QueryDetailsDataGrid and have that retrieve the related records. But I can't get it to work that way.


Thanks
Nathalie
0 Kudos
1 Solution

Accepted Solutions
JMcNeil
Deactivated User
Instead of binding to the SelectedWellsTreeView_SelectedItemChanged Event and Binding with SelectedWellsTreeView.Tag.

Create a GraphicsLayer_PropertyChange Event for your graphics layer which is binded to your FDG (QueryDetailsDataGrid) and bind with the OBJECTID, I threw in a message box so you can double check it is same APN.


  private void GraphicsLayer_PropertyChanged(object sender, PropertyChangedEventArgs e)         {              if (e.PropertyName == "SelectedGraphics" && ResultsDisplay.IsOpen == true && QueryDetailsDataGrid.SelectedGraphics.Count == 1)             {                 GraphicsLayer selectionGraphicslayer = Map.Layers["MySelectionGraphicsLayer"] as GraphicsLayer;                          var objectidi = QueryDetailsDataGrid.SelectedGraphics.First().Attributes["OBJECTID_1"];                 strObjecitID = objectidi.ToString();                 intObjectID = Int32.Parse(strObjecitID);                                    MessageBox.Show(strObjecitID);                                      RelationshipParameter relationshipParameters = new RelationshipParameter()                     {                    Convert.ToInt32(QueryDetailsDataGrid.SelectedGraphics.First().Attributes["OBJECTID"] as string) },                         ObjectIds = new int[] { intObjectID },                        OutFields = new string[] { "*" },                         RelationshipId = 0,                         OutSpatialReference = Map.SpatialReference,                       };                   queryTask.ExecuteRelationshipQueryAsync(relationshipParameters);                                   relateIDstring = apn10;              }          }

View solution in original post

0 Kudos
1 Reply
JMcNeil
Deactivated User
Instead of binding to the SelectedWellsTreeView_SelectedItemChanged Event and Binding with SelectedWellsTreeView.Tag.

Create a GraphicsLayer_PropertyChange Event for your graphics layer which is binded to your FDG (QueryDetailsDataGrid) and bind with the OBJECTID, I threw in a message box so you can double check it is same APN.


  private void GraphicsLayer_PropertyChanged(object sender, PropertyChangedEventArgs e)         {              if (e.PropertyName == "SelectedGraphics" && ResultsDisplay.IsOpen == true && QueryDetailsDataGrid.SelectedGraphics.Count == 1)             {                 GraphicsLayer selectionGraphicslayer = Map.Layers["MySelectionGraphicsLayer"] as GraphicsLayer;                          var objectidi = QueryDetailsDataGrid.SelectedGraphics.First().Attributes["OBJECTID_1"];                 strObjecitID = objectidi.ToString();                 intObjectID = Int32.Parse(strObjecitID);                                    MessageBox.Show(strObjecitID);                                      RelationshipParameter relationshipParameters = new RelationshipParameter()                     {                    Convert.ToInt32(QueryDetailsDataGrid.SelectedGraphics.First().Attributes["OBJECTID"] as string) },                         ObjectIds = new int[] { intObjectID },                        OutFields = new string[] { "*" },                         RelationshipId = 0,                         OutSpatialReference = Map.SpatialReference,                       };                   queryTask.ExecuteRelationshipQueryAsync(relationshipParameters);                                   relateIDstring = apn10;              }          }
0 Kudos