Select to view content in your preferred language

How to bind a Textblock.Text to the Sum of Datagrid Column.

9341
13
05-11-2011 05:58 AM
MattMiley
Deactivated User
I have a query where I filter out Data that populates a datagrid and I need to bind a textblock.Text to the sum of the column "Valves_Turned"
<sdk:DataGrid x:Name="QueryDetailsDataGrid" AutoGenerateColumns="False" HeadersVisibility="Column" Background="White"
           IsReadOnly="True"
           HorizontalScrollBarVisibility="Hidden" Grid.RowSpan="2" Margin="0,-6,0,0">
           <sdk:DataGrid.Columns>
            <sdk:DataGridTextColumn Width="150" Binding="{Binding Attributes[Date]}" Header="Date" CanUserSort="True" SortMemberPath=""/>
            <sdk:DataGridTextColumn Width="70" Binding="{Binding Attributes[Valves_Turned]}" Header="Quantity"/>
            <sdk:DataGridTextColumn Width="462" Binding="{Binding Attributes[Turned_Valve_Numbers]}" Header="Turned Valve Numbers"/>
           </sdk:DataGrid.Columns>
          </sdk:DataGrid>


Valves_Turned doesn't have any null values, its a domain with the value defaulted at 0 and has the ability to go up to 25.

I just want my textblock.Text to show the sum off all the values in that column.

I tried this

text="{Binding Attributes[Valves_Turned].SUM}"


and it doesn't work.
0 Kudos
13 Replies
MattMiley
Deactivated User
Does anyone think I can use the charts from the silverlight toolkit then get a sum from there??

Any ideas would be great...
0 Kudos
DominiqueBroux
Esri Frequent Contributor

Does anyone think I can use the charts from the silverlight toolkit then get a sum from there??

I don't think the silverlight can be useful for that. You have to calculate the sum by yourself anyway.


Any ideas would be great...

Add a property 'Sum' to your view model or to your user control, and calculate the Sum at the same time you set the ItemsSource of the datagrid.

Something like :
 
   Sum = graphics.Select(g => (int)g.Attributes["Valves_Turned"]).Sum();

Then you have only to add a TextBlock somewhere and bind it to this 'Sum' property.

Note that some additional code is needed  if the attributes values are modifiable interactively and if you want that the Sum be recalculated  automatically.
0 Kudos
MattMiley
Deactivated User
Okay this is what I got
//Total
                GraphicsLayer graphicsLayer = MyMap.Layers["Job_PointsValves"] as GraphicsLayer;
                int Sum = graphicsLayer.Select(g => (int)g.Attributes["Valves_Turned"]).Sum();


But now I can't figure out how to bind to "Sum"

<TextBlock x:Name="totaltext" HorizontalAlignment="Left" Margin="19,88,0,0" TextWrapping="Wrap" Text="{Binding RelativeSource=Sum}" VerticalAlignment="Top"/>
            
0 Kudos
DominiqueBroux
Esri Frequent Contributor

int Sum =  ....

You need to create a Dependency Property (or a property raising PropertyChanged event). You can't use a variable for binding.

Then you have to bind the Text to this property in XAML.

If you added the Sum property to your ViewModel, you can just do <TextBlock Text={Binding Sum} />.

If you added the Sum property to the UserControl itself :
  1) Give a name to your UserControl :
<UserControl x:Name="MyUserControl" .......
   2) Bind by using the ElementName : <TextBlock Text={Binding Sum, ElementName=MyUserControl} />
0 Kudos
MattMiley
Deactivated User
Sorry dbroux Im a noob, i dont know how to make user controls from scratch.. My raising PropertyChanged event is the query results
void QueryTask_ExecuteCompleted(object sender, ESRI.ArcGIS.Client.Tasks.QueryEventArgs args)
        {
            FeatureSet featureSet = args.FeatureSet;

            if (featureSet != null && featureSet.Features.Count > 0)
            {
                QueryDetailsDataGrid.ItemsSource = featureSet.Features;

                //CollectionViewSource colViewSource = new CollectionViewSource { Source = featureSet.Features };
                //colViewSource.SortDescriptions.Add(new System.ComponentModel.SortDescription("Attributes[Date]", System.ComponentModel.ListSortDirection.Ascending));
                //QueryDetailsDataGrid.ItemsSource = colViewSource.View;


                // Wrap the itemList in a PagedCollectionView for paging functionality
                PagedCollectionView itemListView = new PagedCollectionView(featureSet);

                // Set the DataPager and ListBox to the same data source.
                dataPager1.Source = itemListView;
                itemListView.SortDescriptions.Add(new System.ComponentModel.SortDescription("Attributes[Date]", System.ComponentModel.ListSortDirection.Ascending));
                QueryDetailsDataGrid.ItemsSource = itemListView;

                //Total
                GraphicsLayer graphicsLayer = MyMap.Layers["Job_PointsValves"] as GraphicsLayer;
                int Sum = graphicsLayer.Select(g => (int)g.Attributes["Valves_Turned"]).Sum();
                

                //zoom to query
                ValveReportMap.ZoomTo(ValveReportMap.Layers["Job_PointsValves"].FullExtent);
            }
            else
            {
                MessageBox.Show("No features returned from query");
            }
        }


There isn't anyway to bind to sum this way?

Or can I just tell it to make sumtext.Text = string.Format("{0}", (Sum));?


If that's not possible can you show me in a little more detail.. 

Thanks!!
0 Kudos
DominiqueBroux
Esri Frequent Contributor
There isn't anyway to bind to sum this way?

Or can I just tell it to make sumtext.Text = string.Format("{0}", (Sum));?


It's no more called a 'binding', but you are right you can also set directly the sum to the TextBlock.
Did you try with your code 'sumtext.Text = string.Format("{0}", (Sum));' ?
It's simpler and it should work.

As a side note, I don't understand why you populate the datagrid with the result of the query task and you calculate the sum from the graphics in a layer. Is it supposed to be the same thing? (did I miss where you initialize the layer from the query result?)
0 Kudos
MattMiley
Deactivated User
I think you might need to read my first post again, all I want is the sum of the values in the Column "Valves_Turned". Hes my code for you to look at

 <esri:Map x:Name="ValveReportMap" Width="695" TimeExtent="{Binding Value, ElementName=MyTimeSlider, Mode=TwoWay}" BorderThickness="0,18,0,0" Margin="0,0,0,-213" Grid.Row="2" Height="209" VerticalAlignment="Bottom">
           <esri:ArcGISTiledMapServiceLayer ID="Background" Visible="True" 
            Url="http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer" />
                    <esri:GraphicsLayer ID="graphicsLayer" />

                    <esri:FeatureLayer ID="Job_PointsValves" DisableClientCaching="True" Where="Valves_Turned > 0"
            AutoSave="False"
            Url="http://xxxxxxxx/ArcGIS/rest/services/Water_Utilities_Department_Job_Log/FeatureServer/0"
            Mode="OnDemand">
            <esri:FeatureLayer.OutFields>
             <sys:String>Date</sys:String>
             <sys:String>Valves_Turned</sys:String>
             <sys:String>Turned_Valve_Numbers</sys:String>
            </esri:FeatureLayer.OutFields>
           </esri:FeatureLayer>
           

          </esri:Map>
                <esriToolkit:TimeSlider x:Name="MyTimeSlider" 
                 Height="20" TimeMode="TimeExtent"
                 MinimumValue="2011/01/01 01:00:00 UTC" 
                 MaximumValue="2011/12/30 01:00:00 UTC"
                 Value="{Binding Text, ElementName=NewValue, Mode=TwoWay}" Margin="84,91,150,0" PlaySpeed="0:24:0" VerticalAlignment="Top" />
                <Button Content="Get Report" Height="23" HorizontalAlignment="Left" Margin="533,-33,0,0" x:Name="Query" VerticalAlignment="Top" Width="75" Click="QuryButton" d:LayoutOverrides="VerticalAlignment" />
                <Button x:Name="Print" Content="Print" Click="PrintValveReport" HorizontalAlignment="Left" Width="75" Margin="617,-33,0,0" VerticalAlignment="Top" />
                <StackPanel Orientation="Horizontal" Margin="0,-35,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="254" >
                 <TextBlock Width="143" Margin="5"
                  Text="Valve Report begin date:" TextWrapping="Wrap" HorizontalAlignment="Right" TextAlignment="Right" />
                 <sdk:DatePicker Height="20" x:Name="dp1" Width="100" SelectedDateChanged="DP1_date_changed" />
                </StackPanel>
                <StackPanel Orientation="Horizontal" Margin="262,-35,182,0" VerticalAlignment="Top" >
                 <TextBlock Width="134" Margin="5"
                  Text="Valve Report end date:" TextWrapping="Wrap" HorizontalAlignment="Right" TextAlignment="Right" />
                    <sdk:DatePicker Height="20" x:Name="dp2" Width="100" SelectedDateChanged="DP2_date_changed" />
                </StackPanel>
                <TextBlock x:Name="StartDate" VerticalAlignment="Top"
                 Text="{Binding SelectedDate, ElementName=dp1, Mode=TwoWay, StringFormat=yyyy-MM-dd}"  Margin="53,91,0,0" d:LayoutOverrides="VerticalAlignment" HorizontalAlignment="Left" Width="250"  />
                <TextBlock x:Name="EndDate" VerticalAlignment="Top"
                 Text="{Binding SelectedDate, ElementName=dp2, Mode=TwoWay, StringFormat=yyyy-MM-dd}" Margin="53,107,0,0" HorizontalAlignment="Left" Width="250" />
                <TextBox x:Name="NewValue" HorizontalAlignment="Left" VerticalAlignment="Top" Width="350"
                 Text="2011-04-01 01:00:00Z,2011-04-30 01:00:00Z" Margin="53,123,0,0" />
                <sdk:DataGrid x:Name="QueryDetailsDataGrid" AutoGenerateColumns="False" HeadersVisibility="Column" Background="White"
                 IsReadOnly="True"
                 HorizontalScrollBarVisibility="Hidden" Grid.RowSpan="2" Margin="0,-6,0,0">
                 <sdk:DataGrid.Columns>
                  <sdk:DataGridTextColumn Width="150" Binding="{Binding Attributes[Date]}" Header="Date" CanUserSort="True" SortMemberPath=""/>
                  <sdk:DataGridTextColumn Width="70" Binding="{Binding Attributes[Valves_Turned]}" Header="Quantity"/>
                  <sdk:DataGridTextColumn Width="462" Binding="{Binding Attributes[Turned_Valve_Numbers]}" Header="Turned Valve Numbers"/>
                 </sdk:DataGrid.Columns>
                </sdk:DataGrid>
                <sdk:DataPager x:Name="dataPager1"
                            PageSize="25"
                            AutoEllipsis="True"
                            NumericButtonCount="3"
                            DisplayMode="PreviousNext"
                            IsTotalItemCountFixed="True" Height="24" VerticalAlignment="Top" Margin="0,-60,0,0"/>
            </Grid>


  private void QuryButton(object sender, RoutedEventArgs e)
        {
            int result = StartDate.Text.CompareTo(EndDate.Text);
            // if StartDate.Text is less than EndDate.Text result will be less than zeor i.e. -1
            // if StartDate.Text is greator than EndDate.Text result will be greator than zeor i.e. 1
            // if StartDate.Text is equal to EndDate.Text result will be zero.
            if (result < 0)
            {
                QueryTask queryTask =
                   new QueryTask("http://utgissvr/ArcGIS/rest/services/Water_Utilities_Department_Job_Log/MapServer/0");
                queryTask.ExecuteCompleted += QueryTask_ExecuteCompleted;
                queryTask.Failed += QueryTask_Failed;

                ESRI.ArcGIS.Client.Tasks.Query query = new ESRI.ArcGIS.Client.Tasks.Query();
                query.TimeExtent = MyTimeSlider.Value;
                query.Where = "Valves_Turned > 0";

                query.OutFields.Add("*");
                queryTask.ExecuteAsync(query);
            }
            if (result == 0)
            {
                MessageBox.Show("The begin date is after the end date.");
            }
            if (result > 0)
            {
                MessageBox.Show("The begin date is after the end date.");
            }
        }   

        void QueryTask_ExecuteCompleted(object sender, ESRI.ArcGIS.Client.Tasks.QueryEventArgs args)
        {
            FeatureSet featureSet = args.FeatureSet;

            if (featureSet != null && featureSet.Features.Count > 0)
            {
                QueryDetailsDataGrid.ItemsSource = featureSet.Features;

                //CollectionViewSource colViewSource = new CollectionViewSource { Source = featureSet.Features };
                //colViewSource.SortDescriptions.Add(new System.ComponentModel.SortDescription("Attributes[Date]", System.ComponentModel.ListSortDirection.Ascending));
                //QueryDetailsDataGrid.ItemsSource = colViewSource.View;


                // Wrap the itemList in a PagedCollectionView for paging functionality
                PagedCollectionView itemListView = new PagedCollectionView(featureSet);

                // Set the DataPager and ListBox to the same data source.
                dataPager1.Source = itemListView;
                itemListView.SortDescriptions.Add(new System.ComponentModel.SortDescription("Attributes[Date]", System.ComponentModel.ListSortDirection.Ascending));
                QueryDetailsDataGrid.ItemsSource = itemListView;

                //Total
                GraphicsLayer graphicsLayer = MyMap.Layers["Job_PointsValves"] as GraphicsLayer;
                int Sum = graphicsLayer.Select(g => (int)g.Attributes["Valves_Turned"]).Sum();
                totalText.Text = string.Format("{0}", (Sum));
                
                //zoom to query
                ValveReportMap.ZoomTo(ValveReportMap.Layers["Job_PointsValves"].FullExtent);
            }
            else
            {
                MessageBox.Show("No features returned from query");
            }
        }

        private void QueryTask_Failed(object sender, TaskFailedEventArgs args)
        {
            MessageBox.Show("Query execute error: " + args.Error);
        }



And unfortunately
//Total
                GraphicsLayer graphicsLayer = MyMap.Layers["Job_PointsValves"] as GraphicsLayer;
                int Sum = graphicsLayer.Select(g => (int)g.Attributes["Valves_Turned"]).Sum();
                totalText.Text = string.Format("{0}", (Sum));


Does not work
0 Kudos
DominiqueBroux
Esri Frequent Contributor

I think you might need to read my first post again, all I want is the sum of the values in the Column "Valves_Turned".

I read it. It's why I warned you that you were populating the datagrid with a list of graphics and calculating the sum from possibly another list.

Try :
int Sum = featureSet.Features.Select(g => (int)g.Attributes["Valves_Turned"]).Sum();
0 Kudos
MattMiley
Deactivated User
Sorry dbroux


Try :
int Sum = featureSet.Features.Select(g => (int)g.Attributes["Valves_Turned"]).Sum();


Does not work.
0 Kudos