How to bind calculated value in c# method to TextBox?

Imilio 41 Reputation points
2022-02-12T21:00:14.63+00:00

I want to calculate the sum of a column in my list(ObservableCollection displayed in ListView) and display it in TextBox.

<ListView x:Name="ProductListView" ItemsSource="{Binding ViewModel}">
<TextBlock Text="{Binding ???, StringFormat={}{0:N2}}" />

I have written a method in my ViewModel for this. But now I don't know how to bind the variable res to TextBox (The TextBox should always be updated when the ListView is changed).

public void CalcTotal()
{
    decimal res = 0;
    for (var i = 0; i < ProductsList.Count; i++)
    {
        res += ProductsList[i].Amount;
    }
}

Thanks!

Developer technologies | Windows Presentation Foundation
{count} votes

2 answers

Sort by: Most helpful
  1. Peter Fleischer (former MVP) 19,341 Reputation points
    2022-02-13T09:21:07.803+00:00

    Hi Imilio,
    instead of method use property binding with your code in getter:

    <ListView x:Name="ProductListView" ItemsSource="{Binding ViewModel}">
    <TextBlock Text="{Binding CalcTotal, StringFormat={}{0:N2}}" />
    

    ...

     public decimal CalcTotal()
     get
       {
         decimal res = 0;
         for (var i = 0; i < ProductsList.Count; i++) res += ProductsList[i].Amount;
         return res;
      }
     }
    

  2. Peter Fleischer (former MVP) 19,341 Reputation points
    2022-02-14T16:59:42.607+00:00

    Hi,
    try following demo:

    XAML:

    <Window x:Class="WpfApp1.Window105"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WpfApp105"
            mc:Ignorable="d"
            Title="Imilio-3053_220214" Height="450" Width="800">
      <Window.DataContext>
        <local:ProductViewModel/>
      </Window.DataContext>
      <StackPanel>
        <Button Content="new Amount" Command="{Binding}"/>
        <ListView ItemsSource="{Binding View}">
          <ListView.View>
            <GridView>
            <GridViewColumn Header="Amount" Width="100" DisplayMemberBinding="{Binding Amount}"/>
          </GridView>
            </ListView.View>
        </ListView>
        <TextBlock Text="{Binding CalcTotal, StringFormat={}{0:N2}, Mode=OneWay}"/>
      </StackPanel>
    </Window>
    

    ViewModels:

    using System;
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Runtime.CompilerServices;
    using System.Windows;
    using System.Windows.Data;
    using System.Windows.Input;
    
    namespace WpfApp105
    {
      public class ProductViewModel : BaseViewModell, ICommand
      {
        public ProductViewModel() => cvs.Source = ProductsList;
        private CollectionViewSource cvs = new CollectionViewSource();
        private ObservableCollection<Data> ProductsList = new ObservableCollection<Data>();
        private Random rnd = new Random();
    
        public ICollectionView View { get => cvs.View; }
    
        public decimal CalcTotal
        {
          get
          {
            decimal res = 0;
            for (var i = 0; i < ProductsList.Count; i++)
            {
              res += ProductsList[i].Amount;
            }
            return res;
          }
        }
    
        public event EventHandler CanExecuteChanged;
        public void Execute(object parameter)
        {
          ProductsList.Add(new Data() { Amount = (decimal)(Math.Round(rnd.NextDouble() * 100,2))});
          RaisePropertyChanged(nameof(CalcTotal));
        }
        public bool CanExecute(object parameter) => true;
      }
    
      public class Data
      {
        public decimal Amount { get; set; } 
      }
    
      public class BaseViewModell : INotifyPropertyChanged
      {
        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void RaisePropertyChanged([CallerMemberName] string propertyName = "") =>
          this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));   
      }
    }
    

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.