在Buttonclick之后如何使用ICommand执行多种方法

问题描述 投票:0回答:2

我缺乏对如何使用ICommand接口连续执行多个方法的理解。理想情况下,我想创建一个通过调用它执行以下4种方法的委托(但它不必一定是委托):

var mongo = DbConn(); //Connection to MongoDB
var artikel = GetArtikel(reorderView); //returns ObservableCollection<ArtikelModel>
var reorder = GetReorder(artikel, reorderView); //returns ReorderModel
Insert(mongo, artikel, reorder); //inserts new reorder into the MongoDB database (one reorder has multiple articles(artikel))

The View(摘录):

<Button Name="btnSave" Margin="3,0,3,0" Content="Save Reorder" 
                    BorderThickness="0" BorderBrush="Green" 
                    Height="30" FontWeight="Bold" FontSize="15" 
                    Background="Green" 
                    VerticalAlignment="Top"
                    Command="{Binding SaveNb}">
</Button>

背后的代码:

public addReorderView() 
        {
            this.DataContext = new addReorderViewModel(this);
        }

ViewModel(需要帮助):

public class addReorderViewModel
    {
        //Hook to class DelegateCommand
        private readonly DelegateCommand<Button> _clickCommand;
        private ICommand saveNb { get; set; }


        public addReorderViewModel(addReorderView reorderview)
        {

        }
    public ICommand SaveNb
            {
                get
                {
                    return saveNb;
                }
                set
                {
                    saveNb = value;
                }
            }

ViewModel具有一个到DelegateCommand.cs-Class的“钩子:DelegateCommand.cs

public class DelegateCommand<T> : System.Windows.Input.ICommand
    {
        private readonly Predicate<T> _canExecute;
        private readonly Action<T> _execute;

        public DelegateCommand(Action<T> execute)
            : this(execute, null)
        {
        }

        public DelegateCommand(Action<T> execute, Predicate<T> canExecute)
        {
            _execute = execute;
            _canExecute = canExecute;
        }

        public bool CanExecute(object parameter)
        {
            if (_canExecute == null)
                return true;

            return _canExecute((parameter == null) ? default(T) : (T)Convert.ChangeType(parameter, typeof(T)));
        }

        public void Execute(object parameter)
        {
            _execute((parameter == null) ? default(T) : (T)Convert.ChangeType(parameter, typeof(T)));
        }

        public event EventHandler CanExecuteChanged;
        public void RaiseCanExecuteChanged()
        {
            if (CanExecuteChanged != null)
                CanExecuteChanged(this, EventArgs.Empty);
        }
    }

问题:

  1. 我该怎么做才能使buttonclick执行以上操作提到了4种方法?

  2. 我如何将其他buttonclick事件(该视图具有约5-10个按钮)添加到ViewModel中?

  3. ViewModel如何知道当前打开的View?

ViewModel中的方法:

public MongoCRUD DbConn()
        {
            //Connection to MongoDB database "avdb"
            var mongo = new MongoCRUD("avdb");
            return mongo; //return value needed for INSERT-METHOD!
        }

        public ObservableCollection<Artikel> GetArtikel()
        {
            //How many rows inside the datagrid dgArtikel?
            int countrows = view.dgArtikel.Items.Count;
            //How many Columns?
            int countcols = view.dgArtikel.Columns.Count;

            //Arrays
            DataGridRow[] row = new DataGridRow[countrows];
            DataGridCell[] RowColumn = new DataGridCell[countcols];
            string[] CellValue = new string[countcols];
            string[,] ds = new string[countrows, countcols];

            ObservableCollection<Artikel> artikel = new ObservableCollection<Artikel>() { };
            //Save all cell values inside multidimensional Array
            for (int i = 0; i < countrows; i++)
            {
                //Create object for each DataGridRow of dgArtikel
                row[i] = (DataGridRow)view.dgArtikel.ItemContainerGenerator.ContainerFromIndex(i);
                //Alle Spalten in der jeweiligen Zeile iterieren
                for (int j = 0; j < view.dgArtikel.Columns.Count; j++)
                {

                    RowColumn[j] = view.dgArtikel.Columns[j].GetCellContent(row[i]).Parent as DataGridCell;
                    //ATTENTION HARDCODING --> j==INDEX COMBOBOXCOLUMN!!!
                    if (j == 7) //<---!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                    {
                        CellValue[j] = ((ComboBox)RowColumn[j].Content).Text;
                    }
                    else
                    {
                        CellValue[j] = ((TextBlock)RowColumn[j].Content).Text;
                    }

                    ds[i, j] = CellValue[j];
                }
                //The sequence must be the same as inside class ARTIKEL!  ATTENTION HARDCODING!
                var art = new Artikel
                {
                    Pos = ds[i, 0],
                    Artikelbezeichnung = ds[i, 1],
                    Artikelnummer = ds[i, 2],
                    Einheit = ds[i, 3],
                    Menge = ds[i, 4],
                    Einzelpreis = ds[i, 5],
                    Gesamtpreis = ds[i, 6],
                    Anforderungsgrund = ds[i, 7], //<---!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                    Anforderungsnr = ds[i, 8],
                    Anforderer = ds[i, 9],
                    Bemerkungen = ds[i, 10]
                };
                if (art != null)
                    artikel.Add(art);
            }
            return artikel;
        }


         public ReorderModel GetReorder(ObservableCollection<Artikel> artikel, addReorderView reorderview)
         {             
            ReorderModel rom = new ReorderModel
            {
                Hv = view.txtbHv.Text,
                Bv = view.txtBv.Text,
                Bauleiter = view.txtBauleiter.Text,
                Empfaenger = view.cboxEmpfaenger.Text,
                Empf_Ansprechpartner = view.txtEmpfAnsprechpartner.Text,
                Empfaenger_Mail = view.txtEmpfMail.Text,
                Anlieferungsort = view.cboxAnlieferung.Text,
                Adressat = view.cboxAdressat.Text,
                Anschrift = view.txtAdresse.Text,
                Plz_Ort = view.txtPlzOrt.Text,
                Kontaktperson_Kontaktnr = view.txtAnsprechpartnerOrt.Text,
                Liefertermin = view.calLiefertermin.Text,
                Bearbeiter = view.cboxBearbeiter.Text,
                Telefon_Bearbeiter = view.txtBearbeiterTel.Text,
                Mail_Bearbeiter = view.txtBearbeiterMail.Text,
                Bestelldatum = view.calBestelldatum.Text,
                Bemerkung_oben = view.txtBemerkung.Text,
                Projektleiter = view.txtProjektleiter.Text,
                Angelegt_am = DateTime.Now.ToString(),
                artikelliste = artikel
            };
            return rom;
         }  

         public void Insert(MongoCRUD mongo, ObservableCollection<Artikel> artikel, ReorderModel rom)
         {
            foreach (var a in artikel)
            {
                mongo.InsertRecord<Artikel>("bestellteArtikel", a);
            }
            mongo.InsertRecord<Nachbestellung>("nachbestellungen", nb);
            MessageBox.Show("Nachbestellung in Datenbank gespeichert!", "Erfolgreich!", MessageBoxButton.OK, MessageBoxImage.Information);
         }   
c# wpf design-patterns icommand
2个回答
0
投票

WPF中的命令是在从UI(单击按钮)生成命令时执行一种方法。现在,您可以在命令上执行4种方法。因此,创建一个包含四个方法调用的方法(或Action),然后将该方法绑定到命令。

在视图模型的构造函数中添加如下内容

public addReorderViewModel()
{
    saveNb  = new DelegateCommand<Button>(() =>{
       var mongo = DbConn(); //Connection to MongoDB
       var artikel = GetArtikel(reorderView); //returns ObservableCollection<ArtikelModel>
       var reorder = GetReorder(artikel, reorderView); //returns ReorderModel
       Insert(mongo, artikel, reorder); //inserts new reorder into the MongoDB database (one reorder has multiple articles(artikel))
    });
}

0
投票
  1. 由于您使用的是DelegateCommand,因此只需正确初始化即可:

AddReorderViewModel.cs

public ICommand SaveNb => new DelegateCommand(ExecuteMethods, CanExecuteMethods);

private void ExecuteMethods(object param)
{ 
  var mongo = DbConn(); //Connection to MongoDB
  var artikel = GetArtikel(reorderView); //returns ObservableCollection<ArtikelModel>
  var reorder = GetReorder(artikel, reorderView); //returns ReorderModel
  Insert(mongo, artikel, reorder); //inserts new reorder into the MongoDB database (one reorder has multiple articles(artikel))
}

private bool CanExecuteMethods(object param)
{ 
  // Check if command can execute 
  if (MongoDb connection exists)
  {
    return true;
  }
  return false;
}
  1. 对于与视图模型通信的所有其他按钮,也请使用ICommand。您只需使用新的Execute和CanExecute委托定义新的ICommand属性。

  2. 视图模型从不应该对视图一无所知。它永远不应在视图上运行。数据发送到视图的唯一方法是使用Binding或事件。视图本身知道何时打开或可见,然后应开始与视图模型进行通信。

© www.soinside.com 2019 - 2024. All rights reserved.