我缺乏对如何使用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);
}
}
问题:
我该怎么做才能使buttonclick执行以上操作提到了4种方法?
我如何将其他buttonclick事件(该视图具有约5-10个按钮)添加到ViewModel中?
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);
}
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))
});
}
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;
}
对于与视图模型通信的所有其他按钮,也请使用ICommand
。您只需使用新的Execute和CanExecute委托定义新的ICommand
属性。
视图模型从不应该对视图一无所知。它永远不应在视图上运行。数据发送到视图的唯一方法是使用Binding
或事件。视图本身知道何时打开或可见,然后应开始与视图模型进行通信。