繁体   English   中英

WPF 多个UI同时更新

[英]WPF multiple UI Update Simultaneously

我在用户控件中有一个数据网格(实际上是购物车)和一个按钮(称为“添加”)。 下面是截图链接。

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

当我点击这个添加按钮时,一个 window 打开显示产品,我在那里输入数量和其他详细信息,然后点击提交这个第二个 window。 下面是截图链接——

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

现在的问题是,当我单击此提交按钮时,有一个更新数据网格的方法 CALled Load 称为 LoadDGStockIN() 由按钮方法“BtnActionSaveNewStockntry()”调用,但在用户控件 UI 中的 Datagrid 中没有更改或更新。

请帮助我在这个领域很新。 这是两个 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

    }
}

您的 ObservableCollection _DGISrcStockIn 不使用 OnPropertyChanged 接口。 你必须像这样在公共集之后调用它

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

在提交对话框后,我看不到任何代码,您可以在其中将项目添加到可观察列表中。

将调用 function “LoadDGStockIN”,并且始终使用相同的 static 项目初始化属性“DGISrcStockIn”。

您需要从对话框中提取数据并将它们添加到绑定的 observable 列表中。

问题解决了。 无需为此使用线程。 只需在创建时将视图模型传递给新的 window。

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

它解决了我的问题。 如果有人有更好的方法请评论或回答。 这将受到高度评价。

您正在破坏 SOLID(此,单一责任)。 为什么 ICommand 包含在 ViewModel 中?

创建 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);
    }
}

创建 Model 和 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();
   }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM