Select to view content in your preferred language

Collection View Source

2950
19
02-04-2011 11:31 AM
MeConfused
Emerging Contributor
I am trying to Sort the results from a buffer using Collection View Source...I think I am on the right path here but cant seem to get the sort to perform or refresh the listbox.
In this case I am trying to sort by the Buffer Distance being created fro each selected feature found inside the buffer
Note: BUFFER_DISTANCE is not a field in the feature...its being created or set below in blue

Any quick thoughts?

    Private Sub QueryTask_ExecuteCompletedBuffer2(ByVal sender As Object, ByVal args As QueryEventArgs)

      ' Set up the collection View Source in order to Sort the results of the query by DISTANCE       
                Dim cs As New CollectionViewSource
                cs.SortDescriptions.Add(New SortDescription("BUFFER_DISTANCE", ListSortDirection.Ascending)) 
                cs.Source = args.FeatureSet.Features        
     ' Apply the sort to the listbox       
                imageListBuffer.ItemsSource = cs.View        
     ' refresh the listbox        
                cs.View.Refresh()

        Dim featureSet As FeatureSet = args.FeatureSet
        imageListBuffer.ItemsSource = args.FeatureSet.Features

        ' Set the Buffer Variable for the Center Point of the buffer to a MAPPOINT not String to the variable being set 
        ' in the GeometryService_BufferCompleted2...the Variable is globally define at the to of the code page
        Dim _XYLocationBuffer As MapPoint = Nothing
        _XYLocationBuffer = _XYLocation

        If args.FeatureSet.Features.Count < 1 Then
            MessageBox.Show("No features found")
            Return
        End If
        For Each selectedGraphic As Graphic In args.FeatureSet.Features
            selectedGraphic.Symbol = TryCast(LayoutRoot.Resources("DefaultMarkerSymbol"), ESRI.ArcGIS.Client.Symbols.Symbol)
            _resultsGraphicsLayer.Graphics.Add(selectedGraphic)

            ' Get the center point of each selected graphic found in the buffer
            Dim c As ESRI.ArcGIS.Client.Geometry.MapPoint = selectedGraphic.Geometry.Extent.GetCenter()
            ' Call the GetDistance Function...Set the Distance to the BUFFER_DISTANCE variable for each graphic, for display in the listbox            
             selectedGraphic.Attributes("BUFFER_DISTANCE") = GetDistance(_XYLocationBuffer, c)
       
 Next selectedGraphic

    End Sub
0 Kudos
19 Replies
MeConfused
Emerging Contributor
Do I need to specify something in the xaml file?  Or should this work the way it is?
0 Kudos
JenniferNery
Esri Regular Contributor
You can look at this sample for using CollectionViewSource http://msdn.microsoft.com/en-us/library/system.windows.data.collectionviewsource(v=VS.95).aspx. Notice that the PropertyName matches a property in the object collection.

What about using DataGrid or FeatureDataGrid where sorting comes for free. Look at this sample: http://help.arcgis.com/en/webapi/silverlight/samples/start.htm#ToolkitFeatureDataGrid. FeatureDataGrid also work with GraphicsLayer, your GraphicsLayer can contain the resulting graphics which also include the new attribute buffer distance. Notice in the live sample, that you can click the header of the column and the column is sorted accordingly.
0 Kudos
JayKappy
Frequent Contributor
Thanks for your reply jennifer....

As for why I am not using a grid etc...I foudn that I can display more data in a confined location with a listbox, where I can format how I want the text to appear.  When teh user does a search there are a series of windows that open along the bottom of my map...like this
http://coolapps.cybertech.com/AppGallery/Government_Service_Locator.aspx


Couple Thoughts:
In the example you pointed me to they have this line in the collection view source
Source="{StaticResource customerSampleData}">


I see that "customerSampleData" is defined above in this example...but in my app I have a listbox...  My results are coming from a Query in my vb page ... I bind the results to the listbox with this
imageListBuffer.ItemsSource = args.FeatureSet.Features

I guess I am confused on how to make the connection from:
1. the listbox which is deifned in xaml
2. the binding of the results in the vb page
3. the assigning of the CVS in the xaml
0 Kudos
MeConfused
Emerging Contributor
Thanks for your reply jennifer....

As for why I am not using a grid etc...I foudn that I can display more data in a confined location with a listbox, where I can format how I want the text to appear. When the user does a search there are a series of windows that open along the bottom of my map...like this
http://coolapps.cybertech.com/AppGallery/Government_Service_Locator.aspx

Couple Thoughts:
In the example you pointed me to they have this line in the collection view source
Source="{StaticResource customerSampleData}">


I see that "customerSampleData" is defined above in this example...but in my app I have a listbox... My results are coming from a Query in my vb page ... I bind the results to the listbox with this in the vb page
imageListBuffer.ItemsSource = args.FeatureSet.Features


I guess I am confused on how to make the connection from:
1. the listbox which is defined in xaml
2. the binding of the results in the vb page to the listbox
3. the assigning of the CVS in the xaml to sort the listbox results



Right now I have this im my xaml page: I have no idea about the source when the source is in my VB page
    <UserControl.Resources>
        <!--<CollectionViewSource x:Name="dataSource" Source="{StaticResource imageListBuffer}">            
            <CollectionViewSource.SortDescriptions>
                <compMod:SortDescription PropertyName="NAME" Direction="Ascending"/>
            </CollectionViewSource.SortDescriptions>
        </CollectionViewSource>-->
    </UserControl.Resources>


<Grid Grid.Column="2">
      <StackPanel Orientation="Vertical" Margin="5" HorizontalAlignment="left" VerticalAlignment="top" >
            <Grid x:Name="IdentifyGridBuffer" HorizontalAlignment="left" VerticalAlignment="Top" Margin="0,2,0,0"  MouseEnter="TurnOnChurchBufferedGraphics">
                <Rectangle Fill="#CC5C90B2" Stroke="Gray" Opacity=".6" RadiusX="10" RadiusY="10" Margin="0,0,0,0" >
                    <Rectangle.Effect>
                        <DropShadowEffect/>
                    </Rectangle.Effect>
                </Rectangle>
                <StackPanel x:Name="IdentifyResultsPanelBuffer" Height="190" Width="300" Orientation="Vertical" Margin="0,20,0,0" HorizontalAlignment="Center">
                    <Grid x:Name="resultsPanelBuffer"  Width="260"  
                        HorizontalAlignment="Center" VerticalAlignment="Top"
                        Margin="10,40,10,10">
                        <Border Padding="2" Style="{StaticResource darkBorder}">
                            <StackPanel Orientation="Vertical" >
                                <ListBox x:Name="imageListBuffer" Height="120"   ScrollViewer.HorizontalScrollBarVisibility="Hidden" ScrollViewer.VerticalScrollBarVisibility="Visible" 
                                            BorderThickness="0"
                                            Foreground="White" Background="Transparent"
                                            SelectionChanged="imageListBuffer_SelectionChanged"
                                         ItemsSource="Binding Source={StaticResource dataSource}"  >
                                    <ListBox.ItemTemplate>
                                        <DataTemplate>
                                            <StackPanel Orientation="Horizontal" VerticalAlignment="Center" >
                                                <!-- QUERY -->
                                                <StackPanel Margin="1">
                                                    <TextBlock Foreground="White" Margin="0,4,0,0" VerticalAlignment="Center" Text="{Binding Attributes[TYPE]}"  />
                                                </StackPanel>
                                                <StackPanel Margin="5,0,0,0" Orientation="Vertical">
                                                    <TextBlock Foreground="White" Text="{Binding Attributes[NAME], StringFormat='Name:     \{0\}'}" >
                                                        <TextBlock.Effect>
                                                            <DropShadowEffect/>
                                                        </TextBlock.Effect>
                                                    </TextBlock>
                                                 </StackPanel>
                                            </StackPanel>
                                        </DataTemplate>
                                    </ListBox.ItemTemplate>
                                </ListBox>
                            </StackPanel>
                        </Border>
                    </Grid>
                </StackPanel>
            </Grid>
        </StackPanel>
</Grid>



VB PAGE - I have this in my vb page and nothing is happening
'..snip
        ' Set up the collection View Source in order to Sort the results of the query by DISTANCE
        Dim cs As New CollectionViewSource
        'cs.SortDescriptions.Add(New SortDescription("BUFFER_DISTANCE", ListSortDirection.Ascending))
        cs.SortDescriptions.Add(New SortDescription("NAME", ListSortDirection.Ascending))
        cs.Source = args.FeatureSet.Features
        ' Apply the sort to the listbox
        imageListBuffer.ItemsSource = cs.View
        ' refresh the listbox
        cs.View.Refresh()

        Dim featureSet As FeatureSet = args.FeatureSet
        ' Set the listbox with all the found features.

        imageListBuffer.ItemsSource = args.FeatureSet.Features
..snip
0 Kudos
JenniferNery
Esri Regular Contributor
In that MSDN sample, they defined their own class Customer and CustomerCollection. They did not show code-behind but it should be a simple class with properties that implements INotifyPropertyChanged and the collection is just an ObservableCollection. I think if you are going to use this approach, you need to create your own model class too with properties that you can sort by.

http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged(v=VS.95).aspx
http://msdn.microsoft.com/en-us/library/system.windows.datatemplate(v=vs.95).aspx
0 Kudos
MeConfused
Emerging Contributor
WOW....I really have no idea what those two sites are saying...ALL that to simply sort results coming from a query into a listbox
So you are saying there is no other way to sort a listbox?  This is the only way?
I am going to have to grab code from both links you sent to piece this all together?
If there was a way to put results from a query into a results windows and format how it shows, and makes the sorting easier then awesome...but this is the only way I see....

In their example they have this Customers Class...you saying that I have to create a class that houses over 20K customers in my city?  This is where I am getting messed up...I have the results from a query that need to feed the listbox...not some created class that has hardcoded values....

Then create some other class that does something with INotifyPropertyChanged...

hmmm might have to rethink this one....anymore thoughts woudl be appreciated...

Public Class Customers
    Inherits ObservableCollection(Of Customer)

    Public Sub New()
        Add(New Customer("Michael", "Anderberg", "12 North Third Street, Apartment 45"))
        Add(New Customer("Chris", "Ashton", "34 West Fifth Street, Apartment 67"))
        Add(New Customer("Cassie", "Hicks", "56 East Seventh Street, Apartment 89"))
        Add(New Customer("Guido", "Pica", "78 South Ninth Street, Apartment 10"))
    End Sub

End Class



I DONT SEE any sorting....Where does the sorting happen in those two classes?

THanks Again
0 Kudos
JenniferNery
Esri Regular Contributor
I'm not saying this is the only way but your question was how to use CollectionViewSource so I gave you the links from MSDN. 🙂

You can also sort the results using Linq and use the sorted results as ListBox ItemsSource.
0 Kudos
MeConfused
Emerging Contributor
Thanks.....Lets start again....I am looking for teh simplest way to sort the results from a query that I have binded to a listbox...
Whats the easiest:confused:

Linq???

I am referencing this but cant convert to VB...I tried a converter but thats messing up...I think I am at least tryign to code in the correct location....grab the resulted set, sort, then bind?????

http://blogs.esri.com/Dev/blogs/silverlightwpf/archive/2010/01/20/Sorting-query-results-using-LINQ.a...

I know I have the code all messed up....I just dont know what I am supposed to be targeting and setting..or if I am even on the right path here.
Query, Sort, Bind?

        Dim featureSet As FeatureSet = args.FeatureSet
        ' Set the listbox with all the found features.

        Dim enumGraphics = From SelectedGraphic In args.FeatureSet SetOrder By TryCast(SelectedGraphic.Attributes("NAME"), String) Ascending
        '  imageListBuffer.ItemsSource = args.FeatureSet.Features       
        imageListBuffer.ItemsSource = enumGraphics

        ' Private _XYLocation As MapPoint = Nothing
        Dim _XYLocationBuffer As MapPoint = Nothing
        _XYLocationBuffer = _XYLocation

        If args.FeatureSet.Features.Count < 1 Then
            MessageBox.Show("No features found")
            Return
        End If
        For Each selectedGraphic As Graphic In args.FeatureSet.Features
            'selectedGraphic.Symbol = TryCast(LayoutRoot.Resources("DefaultMarkerSymbol"), ESRI.ArcGIS.Client.Symbols.Symbol)
            selectedGraphic.Symbol = TryCast(LayoutRoot.Resources("StrobeMarkerSymbol_Blue"), ESRI.ArcGIS.Client.Symbols.Symbol)
            _resultsGraphicsLayer.Graphics.Add(selectedGraphic)
            'graphicsLayer.Graphics.Add(selectedGraphic)

            ' Get the center point of each selected graphic found in the buffer
            Dim c As ESRI.ArcGIS.Client.Geometry.MapPoint = selectedGraphic.Geometry.Extent.GetCenter()
            ' Call the GetDistance Function...Set the Distance to the BUFFER_DISTANCE variable for each graphic, for display in the listbox
            selectedGraphic.Attributes("BUFFER_DISTANCE") = GetDistance(_XYLocationBuffer, c)

        Next selectedGraphic



MAYBE THIS: Am I getting closer

Dim enumGraphics As FeatureSet = args.FeatureSet.OrderBy([NAME], String) Assending
imageListBuffer.ItemsSource = enumGraphics
0 Kudos
JenniferNery
Esri Regular Contributor
For me, I think Linq query might be the easiest solution. Once you have calculated and added the Distance, you can order by this attribute. You can then set ListBox ItemSource with the sortedGraphics.

var sortedGraphics = from g in graphicsLayer.Graphics
   orderby (double)g.Attributes["Distance"] ascending
   select g;
0 Kudos