Click here to Skip to main content
15,886,835 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have an issue when binding value dynamic from cell to cell using DataGrid of WPF. Let me explain my expectation first. I want to create a DataGrid like that:

Quantity | Prices | Pay
(user input) | (user input ) | (auto calculate and display Pay = Quantity * Prices )
the code behide work correctly. But the GUI is not updated. Could you please support me to resolve this issue?

Here is my XAML:

HTML
<grid>
    <datagrid x:name="DGTest" itemssource="{Binding m_Products}" horizontalalignment="Left" margin="40,80,0,0" verticalalignment="Top" height="134" width="414" xmlns:x="#unknown">
              AutoGenerateColumns="False">
        <datagrid.columns>
            <datagridtextcolumn binding="{Binding Quantity, UpdateSourceTrigger=LostFocus}" header="Quantity" width="60" />
            <datagridtextcolumn binding="{Binding Prices, UpdateSourceTrigger=LostFocus}" header="Prices" width="60" />
            <datagridtextcolumn binding="{Binding Pay, UpdateSourceTrigger=LostFocus}" header="Pay" width="60" isreadonly="True" />
        </datagrid.columns>
    </datagrid>

</grid>

Here is my code behide:

C#
MainWindow : Window
{
    ObservableCollection<product> m_Products = new ObservableCollection<product>();
    private class PRODUCT : INotifyPropertyChanged
    {
        int _quantity;
        public int Quantity
        {
            get { return _quantity;  }
            set
            {
                if (_quantity != value)
                {
                    _quantity = value;
                    _pay = _quantity * _prices;
                }
            }
        }
        int _prices;
        public int Prices
        {
            get{ return _prices;  }
            set
            {
                if (_prices != value)
                {
                    _prices = value;
                    _pay = _quantity * _prices;
                }
            }
        }
        int _pay;
        public int Pay
        {
            get { return _pay; }
            set
            {
                if (_pay != value)
                {
                    _prices = value;
                    _pay = _quantity * _prices;
                }
            }
        }
        void OnPropertyChanged(string prop)
        {               
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(prop));
        }
        public event PropertyChangedEventHandler PropertyChanged;
    }
    public MainWindow()
    {

        InitializeComponent();

        m_Products.Add(new PRODUCT { Quantity = 10, Prices = 20, Pay = 200 });
        m_Products.Add(new PRODUCT { Quantity = 2, Prices = 20, Pay = 40 });

        DGTest.ItemsSource = m_Products;

        DataContext = this;
    }
}
Posted
Updated 14-Sep-14 22:27pm
v2

1 solution

I would suggest you replace your product class with the following:

C#
private class PRODUCT : INotifyPropertyChanged
    {
        int _quantity;
        public int Quantity
        {
            get { return _quantity;  }
            set
            {
                if (_quantity != value)
                {
                    _quantity = value;
                    OnPropertyChanged("Quantity");
                    OnPropertyChanged("Pay");
                }
            }
        }
        int _prices;
        public int Prices
        {
            get{ return _prices;  }
            set
            {
                if (_prices != value)
                {
                    _prices = value;
                    OnPropertyChanged("Prices");
                    OnPropertyChanged("Pay");
                }
            }
        }
        int _pay;
        public int Pay
        {
            get { return _quantity * _prices; }
                        
        }
        void OnPropertyChanged(string prop)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(prop));
        }
        public event PropertyChangedEventHandler PropertyChanged;
    }


I would also change this binding by removing the update attribute as below:
XML
<datagridtextcolumn binding="{Binding Pay}" header="Pay" width="60" isreadonly="True" />


As for an explanation, at no point were you telling your GUI to update. To have to call your "OnPropertyChanged" event with the name of the properties that have been updated. When you have a lot of calculated properties this can be a pain, although there are advised solutions around that allow you to partially automate that process.
 
Share this answer
 
v2
Comments
DangBao 15-Sep-14 4:35am    
Great !
It works successful.
Thanks a lot.
Pheonyx 15-Sep-14 4:37am    
No Problem, it took me ages to get my head around that concept when I was learning it myself.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900