0

I have a datagrid (Cart actually) in a usercontrol and a button (called "Add") in it. below is the screenshot link.

https://photos.app.goo.gl/ftGn4e36REwxHVwb9

when i click on this ADD button a window opens showing products there i put quantity and other details and click submit on this this 2nd window . Below is the screenshot link -

https://photos.app.goo.gl/ftBsx1TdKC4WyLNz9

now the problem is when i click on this submit button there is a method CALled Load that updates the datagrid is called LoadDGStockIN() is called by the button method 'BtnActionSaveNewStockntry()' but no change or update in Datagrid that in usercontrol ui.

plz help i am very new in this field. this is the viewmodel for both the UI.

using Pharma.Model;
using Pharma.View;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Threading;

namespace Pharma.ViewModel
{
    internal class VM_StockIn : INotifyPropertyChanged
    {
        #region get set properties
        private  string _VendorName;
        public  string VendorName
        {
            get { return _VendorName; }
            set { _VendorName = value; }
        }

        private  string _MRP;
        public  string MRP
        {
            get { return _MRP; }
            set { _MRP = value; }
        }


        #endregion
        public VM_StockIn()
        {
            MRP = "contrustor loaded";
        }


        #region Button ADD NEW STOCK
        
        private ICommand _BtnAddNewStock;
        public ICommand BtnAddNewStock
        {
            get 
            {
                return _BtnAddNewStock ?? (_BtnAddNewStock = new CommandHandler.CommandHandler(() => BtnAddNewStock_Action(), () => CanExecute)); 
            }
        }

        

        BackgroundWorker backgroundWorker = new();
        Window_StockEntry window;
        private void BtnAddNewStock_Action()
        {
            window = new();
            window.Show();
            threadNo = Thread.CurrentThread.ThreadState.ToString();

        }

        

        #endregion

        #region Button New Stock Entry SAVE
        //public ICommand btnNewStockEntrySave { get; set; }

        

        
        #endregion

        private ObservableCollection<Stock> _DGISrcStockIn = new ObservableCollection<Stock>();
        public ObservableCollection<Stock> DGISrcStockIn
        {
            get { return _DGISrcStockIn; }
            set { _DGISrcStockIn = value; }
        }

        public void LoadDGStockIN()
        {
            Thread.Sleep(1000);
            DGISrcStockIn = new ObservableCollection<Stock>()
            {
                new Stock { SlNo = 01, AvailableQty = 1254, BatchNo = "DF7SE4B3" },
                new Stock { SlNo = 01, AvailableQty = 1254, BatchNo = "DF7SE4B3" },
                new Stock { SlNo = 01, AvailableQty = 1254, BatchNo = "DF7SE4B3" },
                new Stock { SlNo = 01, AvailableQty = 1254, BatchNo = "DF7SE4B3" },
                new Stock { SlNo = 01, AvailableQty = 1254, BatchNo = "DF7SE4B3" },
                new Stock { SlNo = 01, AvailableQty = 1254, BatchNo = "DF7SE4B3" },
                new Stock { SlNo = 01, AvailableQty = 1254, BatchNo = "DF7SE4B3" },
                new Stock { SlNo = 01, AvailableQty = 1254, BatchNo = "DF7SE4B3" },
                new Stock { SlNo = 01, AvailableQty = 1254, BatchNo = "DF7SE4B3" },
                new Stock { SlNo = 81, AvailableQty = 1254, BatchNo = "DF7SE4B3" }
            };

            OnPropertyChanged(nameof(DGISrcStockIn));

            //MessageBox.Show("Datagrid Load Complete");
            VendorName = "new name";
            OnPropertyChanged(nameof(VendorName));
            MRP = "NO MRP 01";
            OnPropertyChanged(nameof(MRP));
            //OnPropertyChanged(nameof(View.User_Control.UC_StockIn));
        }

        #region OnProperty Block
        public event PropertyChangedEventHandler? PropertyChanged;
        protected void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
        #endregion

        #region button New Stock Entry SAVE

        private ICommand _btnNewStockEntrySave;
        public ICommand btnNewStockEntrySave
        {
            get 
            {
                return _btnNewStockEntrySave ?? (_btnNewStockEntrySave = new CommandHandler.CommandHandler(() => BtnActionSaveNewStockntry(), () => CanExecute)); 
            }
        }

        public bool CanExecute 
        {
            get { return true;  }
        }


        
        private void BtnActionSaveNewStockntry()
        {
           
              LoadDGStockIN();
            
        }



        #endregion

    }
}
1
  • Please load screenshots to SO. Commented Dec 17, 2021 at 7:35

4 Answers 4

1

Your ObservableCollection _DGISrcStockIn does not use the OnPropertyChanged interface. You have to call it after the public set like so

private ObservableCollection<Stock> _DGISrcStockIn = new ObservableCollection<Stock>();
public ObservableCollection<Stock> DGISrcStockIn
{
    get { return _DGISrcStockIn; }
    set { _DGISrcStockIn = value; OnPropertyChanged(); }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for answering but it's not working 😔
0

I can not see any code, where you add an item to the observable list, after submit of the dialog.

the function "LoadDGStockIN" will be called and there is a initialization of the Property "DGISrcStockIn" with always the same static items.

You need to extract the data from the dialog and add them to the bound observable list.

2 Comments

Yes u r right .. no code to add to the observable list but the static items even is not showing in the grid. And this problem is not only with the datagrid, rather in any control of usercontrol is not updating even.
If i call this method "LoadDGStockIN()" from default constructor of the viewmodel the usercontrol works fine. But if i call the same method from Button Command 'BtnActionSaveNewStockntry()' it's only updates Window_StockEntry window's controls only
0

Problem solved ! no need to use threading here for this purpose. Just pass the viewmodel to the new window while creating.

   window = new();
   window.DataContext = this;
   window.Show();

it has solved my problem. If any one has better approach plz comment or answer. That will be highly appriciated.

Comments

0

You are breaking SOLID (this, Single Responsobility). Why ICommand contains in ViewModel?

Create class Command:

class Command : ICommand
{

    private Action<object> _execute;
    private Func<object, bool> _canExecute;

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }
    public Command(Action<object> execute, Func<object, bool> canExecute = null)
    {
        _execute = execute;
        _canExecute = canExecute;
    }

    public bool CanExecute(object parameter)
    {
        return _canExecute == null || CanExecute(parameter);
    }

    public void Execute(object parameter)
    {

        _execute(parameter);
    }
}

Create Model and ViewModel:

class Product
{
    public string Name { get; set; }
    public int Price { get; set; }
}
class ProductViewModel
{
    //for DataGrid. ObservableCollection implements INotifyPropertyChanged
    public ObservableCollection<Product> Products { get; set; }

    public ProductViewModel()
    {
        Products = new ObservableCollection<Product>();
        Products.Add(new Product { Name = "Apple", Price = 1});
        Products.Add(new Product { Name = "Banana", Price = 2});
    }

    
    public Command AddProductCommand
    {
        get => new Command((_) =>
        {
            Products.Add(new Product { Name = "Orange", Price = 3 });
        });
    }
}

XAML (MainWindow.xaml):

<DataGrid ItemsSource="{Binding Products}"></DataGrid>
<Button Content="Add product" Command="{Binding AddProductCommand}"></Button>

MainWindow.xaml.cs:

class MainWindow : Window
{
   public MainWindow()
   {
      InitializeComponent();
      this.DataContext = new ProductViewModel();
   }
}

1 Comment

i have done this already my command is named as CommandHandler, but i ahve not done this part like your - public Command AddProductCommand { get => new Command((_) => { Products.Add(new Product { Name = "Orange", Price = 3 }); }); }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.