单击按钮后如何使用命令执行多个方法
How to use ICommand for executing multiple methods after Buttonclick
我不太了解如何使用 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))
观点(节选):
<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 partial class addReorder : System.Windows.Window
{
ReorderViewModel nachbest;
ArtikelViewModel artikel;
//IControllerNachbestellung controllerNachbestellung;
//IModelNachbestellung modelNachbestellung;
public ObservableCollection<string> AnfCollection { get; set; }
public addReorder()
{
this.DataContext = new addReorderViewModel();
}
public addReorder(string hv)
{
InitializeComponent();
//HV, BV, Projektleiter und Bauleiter holen
var dbOracle = new Datenbank();
txtBv.Text = dbOracle.GetBauvorhaben(hv);
txtbHv.Text = hv;
txtBauleiter.Text = dbOracle.GetBauleiter(hv);
string pl = dbOracle.GetProjektleiter(hv);
txtProjektleiter.Text = dbOracle.GetProjektleiter(hv);
nachbest = new ReorderViewModel();
artikel = new ArtikelViewModel();
leftStPnl.DataContext = nachbest;
rightStPnl.DataContext = nachbest;
dgArtikel.DataContext = artikel;
//Die Anforderungscollection wird befüllt
IAnforderungsgrund anfgruende = new Anforderungsgrund();
AnfCollection = anfgruende.ListeAnforderungen();
dgcbAnf.ItemsSource = AnfCollection;
dgcbAnf.TextBinding = new Binding(AnfCollection.ToString());
}
}
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 有一个 "hook" 到 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个方法?
如何将其他按钮单击事件(视图有大约 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);
}
这是视图设计:
这是视图设计中的数据网格(虚拟示例)
绿色按钮是我想借助 ICommand 接口执行的插入部分,即点击后执行以下操作:
连接到 MongoDB
给我 observableCollection()
给我 ReorderModel 实例
插入我的数据库集合
XAML:
<Window x:Class="Nachbestellungen.neueNachbestellung"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Nachbestellungen"
mc:Ignorable="d"
WindowStartupLocation="CenterScreen"
FontFamily="Arial Narrow"
Title="Nachbestellungen" Height="900" Width="900" FontWeight="Bold">
<Window.Resources>
<!-- Abstand zwischen Textblock und Textbox automatisch setzen -->
<Style TargetType="TextBox">
<Setter Property="Margin" Value="0,0,0,0"/>
</Style>
</Window.Resources>
<Grid Name="uInputGrid">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<!-- links -->
<StackPanel Grid.Column="0" Margin="25,25,0,0" x:Name="leftStPnl">
<StackPanel x:Name="pnlHeader" Grid.Column="0" Grid.Row="0" Orientation="Vertical">
<TextBlock Name="tbNb" Grid.Row="0" Grid.Column="0" Text="NACHBESTELLUNG" FontWeight="Bold" FontSize="20"/>
</StackPanel>
<StackPanel x:Name="pnlBv" Grid.Column="0" Grid.Row="1" Margin="0,10,0,0" Orientation="Horizontal">
<TextBlock Name="tbBv" Text="Bauvorhaben" DockPanel.Dock="Left" FontSize="14" FontWeight="Bold"/>
<TextBox Name="txtBv" FontSize="12" DockPanel.Dock="Right" IsEnabled="False" Width="150" Margin="68,0,0,0"></TextBox>
</StackPanel>
<StackPanel x:Name="pnlHv" Grid.Column="0" Grid.Row="2" Margin="0,10,0,0" Orientation="Horizontal">
<TextBlock Name="tbHv" Grid.Column="0" Text="HV-Nummer" FontSize="14" FontWeight="Bold"/>
<TextBox x:Name="txtbHv" FontSize="12" IsEnabled="False" Width="60" Margin="72,0,0,0"/>
</StackPanel>
<StackPanel x:Name="pnlBauleiter" Grid.Column="0" Grid.Row="3" Margin="0,10,0,0" Orientation="Horizontal">
<TextBlock Name="tbBauleiter" Text="Bauleiter" FontSize="14" FontWeight="Bold"/>
<TextBox x:Name="txtBauleiter" FontSize="12" IsEnabled="False" Width="150" Margin="90,0,0,0"/>
</StackPanel>
<StackPanel x:Name="pnlGap1" Grid.Column="0" Grid.Row="4" Margin="0,10,0,0" Orientation="Horizontal">
</StackPanel>
<StackPanel x:Name="pnlEmpfaenger" Grid.Column="0" Grid.Row="5" Margin="0,10,0,0" Orientation="Horizontal">
<TextBlock Name="tbEmpfaenger" Text="AN" FontSize="14" FontWeight="Bold"/>
<ComboBox x:Name="cboxEmpfaenger" FontSize="12" Width="150" Margin="118,0,0,0" Loaded="ComboBox_Loaded" SelectionChanged="ComboBox_Changed">
</ComboBox>
</StackPanel>
<StackPanel x:Name="pnlEmpfAnsprechpartner" Grid.Column="0" Grid.Row="6" Margin="0,10,0,0" Orientation="Horizontal">
<TextBlock Name="tbEmpfAnsprechpartner" Text="Ansprechpartner" FontSize="14" FontWeight="Bold"/>
<TextBox x:Name="txtEmpfAnsprechpartner" FontSize="12" IsEnabled="False" Width="150" Margin="50,0,0,0"/>
</StackPanel>
<StackPanel x:Name="pnlEmpfMail" Grid.Column="0" Grid.Row="7" Margin="0,10,0,0" Orientation="Horizontal">
<TextBlock Name="tbEmpfMail" Text="Mailadresse" FontSize="14" FontWeight="Bold"/>
<TextBox x:Name="txtEmpfMail" FontSize="12" IsEnabled="False" Width="150" Margin="73,0,0,0"/>
</StackPanel>
<StackPanel x:Name="pnlGap2" Grid.Column="0" Grid.Row="8" Margin="0,10,0,0" Orientation="Horizontal">
</StackPanel>
<StackPanel x:Name="pnlAnlieferung" Grid.Column="0" Grid.Row="9" Margin="0,10,0,0" Orientation="Horizontal">
<TextBlock Name="tbAnlieferung" Text="Anlieferung" FontSize="14" FontWeight="Bold"/>
<ComboBox x:Name="cboxAnlieferung" FontSize="12" Width="150" Margin="77,0,0,0" Loaded="ComboBoxAnlieferung_Loaded" SelectionChanged="ComboBoxAnlieferung_Changed"/>
</StackPanel>
<StackPanel x:Name="pnlBauherr" Grid.Column="0" Grid.Row="10" Margin="0,10,0,0" Orientation="Horizontal">
<TextBlock Name="tbBauherr" FontSize="14" FontWeight="Bold"/>
<ComboBox x:Name="cboxAdressat" FontSize="12" IsEnabled="False" Width="200" Margin="135,0,0,0" DropDownClosed="CboxAdressat_DropDownClosed"/>
</StackPanel>
<StackPanel x:Name="pnlAdresse" Grid.Column="0" Grid.Row="11" Margin="0,10,0,0" Orientation="Horizontal">
<TextBlock Name="tbAdresse" FontSize="14" FontWeight="Bold" Text="Adresse"/>
<TextBox x:Name="txtAdresse" FontSize="12" IsEnabled="False" Width="150" Margin="93,0,0,0"/>
</StackPanel>
<StackPanel x:Name="pnlPlzOrt" Grid.Column="0" Grid.Row="12" Margin="0,10,0,0" Orientation="Horizontal">
<TextBlock Name="tbPlzOrt" FontSize="14" FontWeight="Bold"/>
<TextBox x:Name="txtPlzOrt" FontSize="12" IsEnabled="False" Width="150" Margin="135,0,0,0"/>
</StackPanel>
<StackPanel x:Name="pnlGap3" Grid.Column="0" Grid.Row="13" Margin="0,10,0,0" Orientation="Horizontal">
</StackPanel>
<StackPanel x:Name="pnlAnsprechpartnerOrt" Grid.Column="0" Grid.Row="14" Margin="0,10,0,0" Orientation="Horizontal">
<TextBlock Name="tbAnsprechpartnerOrt" FontSize="14" FontWeight="Bold" Text="Ansprechpartner vor Ort/Telefon"/>
<TextBox x:Name="txtAnsprechpartnerOrt" FontSize="12" Width="190" Margin="50,0,0,0" AcceptsReturn="False"/>
<Button x:Name="btnKontakt" Content="Kontakt auswählen" FontSize="12" Click="btnKontakt_Click" />
</StackPanel>
<StackPanel x:Name="pnlBemerkung" Grid.Column="0" Grid.Row="14" Margin="0,10,0,0" Orientation="Horizontal">
<TextBlock Name="tbBemerkung" FontSize="14" FontWeight="Bold" Text="Bemerkung"/>
<TextBox x:Name="txtBemerkung" FontSize="12" Width="250" Height="40" Margin="76,0,0,0" AcceptsReturn="False"/>
</StackPanel>
<StackPanel x:Name="pnlLiefertermin" Grid.Column="0" Grid.Row="15" Margin="0,10,0,0" Orientation="Horizontal">
<TextBlock Name="tbLiefertermin" FontSize="14" FontWeight="Bold" Text="Liefertermin"/>
<DatePicker x:Name="calLiefertermin" FontSize="12" Width="160" Margin="75,0,0,0" IsTodayHighlighted="true"/>
</StackPanel>
</StackPanel>
<!--rechts-->
<StackPanel Grid.Column="1" Margin="0,25,25,0" x:Name="rightStPnl">
<StackPanel x:Name="pnlLuxLogo" Grid.Column="1" Grid.Row="0" Margin="0,10,0,0" Orientation="Vertical">
<Image Source="Z:\SchaeferT\Projekte\Haustechnik\Nachbestellungen\Nachbestellungen\LuxLogo.png" Width="200" Height="30" HorizontalAlignment="Left"/>
</StackPanel>
<StackPanel x:Name="pnlFirma" Grid.Column="1" Grid.Row="1" Margin="0,27,0,0" Orientation="Vertical">
<TextBlock x:Name="tbFirma" FontSize="12" Text="Lux Projektmanagement GmbH & Co. KG"/>
</StackPanel>
<StackPanel x:Name="pnlFirmaAnschrift" Grid.Column="1" Grid.Row="2" Margin="0,10,0,0" Orientation="Vertical">
<TextBlock x:Name="tbFirmaAnschrift" FontSize="12" Text="Pleinfelder Straße 64"/>
</StackPanel>
<StackPanel x:Name="pnlFirmaPlzOrt" Grid.Column="1" Grid.Row="3" Margin="0,10,0,0" Orientation="Vertical">
<TextBlock x:Name="tbFirmaPlzOrt" FontSize="12" Text="91166 Georgensgmünd"/>
</StackPanel>
<StackPanel x:Name="pnlRightGap1" Grid.Column="1" Grid.Row="4" Margin="0,10,0,0" Orientation="Horizontal">
</StackPanel>
<StackPanel x:Name="pnlBearbeiter" Grid.Column="1" Grid.Row="5" Margin="0,10,0,0" Orientation="Horizontal">
<TextBlock Name="tbBearbeiter" FontSize="14" FontWeight="Bold" Text="Bearbeiter"/>
<ComboBox x:Name="cboxBearbeiter" FontSize="12" Width="150" Margin="30,0,0,0" Loaded="ComboBoxBearbeiter_Loaded" SelectionChanged="ComboBoxBearbeiter_Changed"/>
</StackPanel>
<StackPanel x:Name="pnlBearbeiterTel" Grid.Column="0" Grid.Row="6" Margin="0,10,0,0" Orientation="Horizontal">
<TextBlock Name="tbBearbeiterTel" FontSize="14" FontWeight="Bold" Text="Telefon"/>
<TextBox x:Name="txtBearbeiterTel" FontSize="12" IsEnabled="False" Width="150" Margin="45,0,0,0"/>
</StackPanel>
<StackPanel x:Name="pnlBearbeiterMail" Grid.Column="0" Grid.Row="7" Margin="0,10,0,0" Orientation="Horizontal">
<TextBlock Name="tbBearbeiterMail" FontSize="14" FontWeight="Bold" Text="Mail"/>
<TextBox x:Name="txtBearbeiterMail" FontSize="12" IsEnabled="False" Width="150" Margin="62,0,0,0"/>
</StackPanel>
<StackPanel x:Name="pnlBestelldatum" Grid.Column="0" Grid.Row="8" Margin="0,10,0,0" Orientation="Horizontal">
<TextBlock Name="tbBestelldatum" FontSize="14" FontWeight="Bold" Text="Best.-Datum"/>
<DatePicker x:Name="calBestelldatum" FontSize="12" Width="200" Margin="19,0,0,0" IsTodayHighlighted="true"/>
</StackPanel>
<StackPanel x:Name="pnlRightGap2" Grid.Column="1" Grid.Row="9" Margin="0,10,0,0" Orientation="Horizontal">
</StackPanel>
<StackPanel x:Name="pnlRightGap3" Grid.Column="1" Grid.Row="10" Margin="0,10,0,0" Orientation="Horizontal">
</StackPanel>
<StackPanel x:Name="pnlHinweis" Grid.Column="1" Grid.Row="11" Orientation="Vertical">
<TextBlock x:Name="tbHinweis" FontSize="12">
<Run Text=" Bitte geben sie auf ihren Dokumenten immer folgende Informationen an:
• Name des Bauvorhabens
• HV-Nummer und/oder Kostenstelle
• Name des Bestellers
• Abholer (nur bei Abholungen)
Entsprechende Angaben sind in dieser Bestellung fett/kursiv markiert. "/>
<Run FontFamily="Verdana" FontSize="11" Text="Rechnungen mit unvollständigen Angaben müssen wir ab dem 01.12.2013 ungebucht an sie zurücksenden. "/>
</TextBlock>
</StackPanel>
<StackPanel x:Name="pnlProjektleiter" Grid.Column="0" Grid.Row="14" Margin="0,10,0,0" Orientation="Horizontal">
<TextBlock Name="tbProjektleiter" FontSize="14" FontWeight="Bold" Text="Projektleiter"/>
<TextBox x:Name="txtProjektleiter" Text="{Binding Projektleiter, Mode=OneWay}" FontSize="12" IsEnabled="False" Width="225" Margin="50,0,0,0" AcceptsReturn="False"/>
</StackPanel>
</StackPanel>
<!-- unten -->
<DataGrid x:Name="dgArtikel" ItemsSource="{Binding Artikel}" Margin="5" Grid.Row="1" Grid.ColumnSpan="2"
SelectionMode="Single" SelectionUnit="Cell" IsReadOnly="False"
CanUserAddRows="True" CanUserDeleteRows="True" AutoGenerateColumns="False"
BorderBrush="Black" BorderThickness="2" RowHeight="30" FontFamily="Arial Narrow" FontSize="18"
LostFocus="DgArtikel_LostFocus" GotFocus="DgArtikel_GotFocus">
<!-- Style Column Headers -->
<DataGrid.Resources>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="Foreground" Value="#FFFFFF"/>
<Setter Property="Background" Value="#DD002C"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="BorderThickness" Value="0,0,1,2"/>
<Setter Property="BorderBrush" Value="Black"/>
<Setter Property="FontSize" Value="18"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="Height" Value="30"/>
</Style>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn Header="Pos" Binding="{Binding Pos}"/>
<DataGridTextColumn Header="Artikelbezeichnung" Binding="{Binding Artikelbezeichnung}"/>
<DataGridTextColumn Header="Artikelnummer" Binding="{Binding Artikelnummer}"/>
<DataGridTextColumn Header="Einheit" Binding="{Binding Einheit}"/>
<DataGridTextColumn Header="Menge" Binding="{Binding Menge}"/>
<DataGridTextColumn Header="Einzelpreis" Binding="{Binding Einzelpreis}"/>
<DataGridTextColumn Header="Gesamtpreis" Binding="{Binding Gesamtpreis}"/>
<DataGridComboBoxColumn Header="Anforderungsgrund" x:Name="dgcbAnf" ItemsSource="{Binding Anforderungsgrund}"/>
<DataGridTextColumn Header="Anforderungsnr" Binding="{Binding Anforderungsnr}"/>
<DataGridTextColumn Header="Anforderer" Binding="{Binding Anforderer}"/>
<DataGridTextColumn Header="Bemerkungen" Binding="{Binding Bemerkungen}"/>
</DataGrid.Columns>
</DataGrid>
<Border x:Name="borderBtnArtikel" Grid.Row="2" Grid.Column="0" Margin="25,0,0,0" CornerRadius="10" BorderBrush="Black" BorderThickness="2" Background="PaleVioletRed" HorizontalAlignment="Left">
<Button Name="btnArtikel" Margin="3,0,3,0" Content="Artikel suchen" Height="30" FontWeight="Bold" FontSize="15" Background="PaleVioletRed" Click="BtnArtikel_Click" VerticalAlignment="Top" BorderThickness="0" BorderBrush="PaleVioletRed"></Button>
</Border>
<Border x:Name="borderBtnVorhanden" Grid.Row="2" Grid.Column="0" Margin="0,0,25,0" CornerRadius="10" BorderBrush="Black" BorderThickness="2" Background="Yellow" HorizontalAlignment="Right">
<Button Name="btnVorhanden" Margin="3,0,3,0" Content="Vorhandene Nb Aufrufen" Height="30" FontWeight="Bold" FontSize="15" Background="Yellow" Click="BtnVorhanden_Click" VerticalAlignment="Top" BorderThickness="0" BorderBrush="Yellow"></Button>
</Border>
<Border Grid.Row="2" Grid.Column="1" CornerRadius="10" BorderBrush="Black" BorderThickness="2" Background="Green" Margin="25,0,0,0" HorizontalAlignment="Left">
<Button Name="btnSpeichern" Margin="3,0,3,0" Content="Neue Nb Speichern"
BorderThickness="0" BorderBrush="Green"
Height="30" FontWeight="Bold" FontSize="15"
Background="Green"
VerticalAlignment="Top"
Command="{Binding SaveNb}"
>
</Button>
<!-- Click="BtnSpeichern_Click" -->
</Border>
<Border Grid.Row="2" Grid.Column="1" CornerRadius="10" BorderBrush="Black" BorderThickness="2" Background="Orange" HorizontalAlignment="Right" Margin="0,0,25,0">
<Button Name="btnOutlook" Margin="3,0,3,0" Content="Nb per Outlook versenden" Height="30" BorderThickness="0" BorderBrush="Orange" FontWeight="Bold" FontSize="15" Background="Orange" Click="BtnOutlook_Click"></Button>
</Border>
</Grid>
如您所见,Outlook 操作(橙色按钮)在非常糟糕的设计中仍然与 CodeBehind 中的 BtnOutlook_Click 事件处理程序紧密耦合。因此,在将 Green SaveNb Button 正确绑定到上述 4 个方法之后,我将继续使用此按钮和其他按钮,将它们与 CodeBehind 一个一个解耦,以便根据标准约定获得更好的可重用性和灵活性代码。
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<object>(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
或事件。视图本身知道它何时打开或可见,然后应该开始与视图模型通信。
编辑
查看 C# 代码:
public partial class addReorder : System.Windows.Window
{
public addReorder(string hvId)
{
InitializeComponent();
this.DataContext = new addReorderViewModel(hvId);
}
}
查看模型:
public class addReorderViewModel
{
public addReorderViewModel(string hvId)
{
InitializeReorderModel(hvId);
this.ArtikelList = new ObservableCollection<Artikel>();
//Die Anforderungscollection wird befüllt
IAnforderungsgrund anfgruende = new Anforderungsgrund();
this.AnfCollection = anfgruende.ListeAnforderungen();
}
public InitializeReorderModel(string hvId)
{
this.Nachbest = new ReorderModel();
//HV, BV, Projektleiter und Bauleiter holen
var dbOracle = new Datenbank();
this.Nachbest.BV = dbOracle.GetBauvorhaben(hv);
this.Nachbest.Hv = hv;
this.Nachbest.Bauleiter = dbOracle.GetBauleiter(hv);
this.Nachbest.Projektleiter = dbOracle.GetProjektleiter(hv);
}
private void ExecuteMethods(object param)
{
var mongo = DbConn(); //Connection to MongoDB
var artikel = this.ArtikelList; //returns ObservableCollection<ArtikelModel>
var reorder = this.Nachbest; //returns ReorderModel
Insert(mongo, artikel, reorder); //inserts new reorder into the MongoDB database (one reorder has multiple articles(artikel))
}
public ICommand SaveNb => new DelegateCommand<object>(ExecuteMethods, CanExecuteMethods);
public ReorderViewModel Nachbest {get; set;}
public ObservableCollection<string> AnfCollection {get; set;}
public ObservableCollection<Artikel> ArtikelList {get; set;}
}
XAML 片段:
<!-- links -->
<StackPanel x:Name="leftStPnl" DataContext="{Binding Nachbest}" ... >
<StackPanel x:Name="pnlBv" Grid.Column="0" Grid.Row="1" Margin="0,10,0,0" Orientation="Horizontal">
<TextBlock Name="tbBv" Text="Bauvorhaben" DockPanel.Dock="Left" FontSize="14" FontWeight="Bold"/>
<TextBox Name="txtBv" Text="{Binding Bv }" />
</StackPanel>
<StackPanel x:Name="pnlHv" Grid.Column="0" Grid.Row="2" Margin="0,10,0,0" Orientation="Horizontal">
<TextBlock Name="tbHv" Grid.Column="0" Text="HV-Nummer" FontSize="14" FontWeight="Bold"/>
<TextBox x:Name="txtbHv" Text="{Binding Hv}"/>
</StackPanel>
...
</StackPanel>
<!-- rechts -->
<StackPanel x:Name="rightStPnl" DataContext="{Binding Nachbest}" ... >
...
</StackPanel>
<DataGrid x:Name="dgArtikel" ItemsSource="{Binding ArtikelList}" ... >
...
</DataGrid>
我不太了解如何使用 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))
观点(节选):
<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 partial class addReorder : System.Windows.Window
{
ReorderViewModel nachbest;
ArtikelViewModel artikel;
//IControllerNachbestellung controllerNachbestellung;
//IModelNachbestellung modelNachbestellung;
public ObservableCollection<string> AnfCollection { get; set; }
public addReorder()
{
this.DataContext = new addReorderViewModel();
}
public addReorder(string hv)
{
InitializeComponent();
//HV, BV, Projektleiter und Bauleiter holen
var dbOracle = new Datenbank();
txtBv.Text = dbOracle.GetBauvorhaben(hv);
txtbHv.Text = hv;
txtBauleiter.Text = dbOracle.GetBauleiter(hv);
string pl = dbOracle.GetProjektleiter(hv);
txtProjektleiter.Text = dbOracle.GetProjektleiter(hv);
nachbest = new ReorderViewModel();
artikel = new ArtikelViewModel();
leftStPnl.DataContext = nachbest;
rightStPnl.DataContext = nachbest;
dgArtikel.DataContext = artikel;
//Die Anforderungscollection wird befüllt
IAnforderungsgrund anfgruende = new Anforderungsgrund();
AnfCollection = anfgruende.ListeAnforderungen();
dgcbAnf.ItemsSource = AnfCollection;
dgcbAnf.TextBinding = new Binding(AnfCollection.ToString());
}
}
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 有一个 "hook" 到 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个方法?
如何将其他按钮单击事件(视图有大约 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);
}
这是视图设计:
绿色按钮是我想借助 ICommand 接口执行的插入部分,即点击后执行以下操作:
连接到 MongoDB
给我 observableCollection()
给我 ReorderModel 实例
插入我的数据库集合
XAML:
<Window x:Class="Nachbestellungen.neueNachbestellung"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Nachbestellungen"
mc:Ignorable="d"
WindowStartupLocation="CenterScreen"
FontFamily="Arial Narrow"
Title="Nachbestellungen" Height="900" Width="900" FontWeight="Bold">
<Window.Resources>
<!-- Abstand zwischen Textblock und Textbox automatisch setzen -->
<Style TargetType="TextBox">
<Setter Property="Margin" Value="0,0,0,0"/>
</Style>
</Window.Resources>
<Grid Name="uInputGrid">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<!-- links -->
<StackPanel Grid.Column="0" Margin="25,25,0,0" x:Name="leftStPnl">
<StackPanel x:Name="pnlHeader" Grid.Column="0" Grid.Row="0" Orientation="Vertical">
<TextBlock Name="tbNb" Grid.Row="0" Grid.Column="0" Text="NACHBESTELLUNG" FontWeight="Bold" FontSize="20"/>
</StackPanel>
<StackPanel x:Name="pnlBv" Grid.Column="0" Grid.Row="1" Margin="0,10,0,0" Orientation="Horizontal">
<TextBlock Name="tbBv" Text="Bauvorhaben" DockPanel.Dock="Left" FontSize="14" FontWeight="Bold"/>
<TextBox Name="txtBv" FontSize="12" DockPanel.Dock="Right" IsEnabled="False" Width="150" Margin="68,0,0,0"></TextBox>
</StackPanel>
<StackPanel x:Name="pnlHv" Grid.Column="0" Grid.Row="2" Margin="0,10,0,0" Orientation="Horizontal">
<TextBlock Name="tbHv" Grid.Column="0" Text="HV-Nummer" FontSize="14" FontWeight="Bold"/>
<TextBox x:Name="txtbHv" FontSize="12" IsEnabled="False" Width="60" Margin="72,0,0,0"/>
</StackPanel>
<StackPanel x:Name="pnlBauleiter" Grid.Column="0" Grid.Row="3" Margin="0,10,0,0" Orientation="Horizontal">
<TextBlock Name="tbBauleiter" Text="Bauleiter" FontSize="14" FontWeight="Bold"/>
<TextBox x:Name="txtBauleiter" FontSize="12" IsEnabled="False" Width="150" Margin="90,0,0,0"/>
</StackPanel>
<StackPanel x:Name="pnlGap1" Grid.Column="0" Grid.Row="4" Margin="0,10,0,0" Orientation="Horizontal">
</StackPanel>
<StackPanel x:Name="pnlEmpfaenger" Grid.Column="0" Grid.Row="5" Margin="0,10,0,0" Orientation="Horizontal">
<TextBlock Name="tbEmpfaenger" Text="AN" FontSize="14" FontWeight="Bold"/>
<ComboBox x:Name="cboxEmpfaenger" FontSize="12" Width="150" Margin="118,0,0,0" Loaded="ComboBox_Loaded" SelectionChanged="ComboBox_Changed">
</ComboBox>
</StackPanel>
<StackPanel x:Name="pnlEmpfAnsprechpartner" Grid.Column="0" Grid.Row="6" Margin="0,10,0,0" Orientation="Horizontal">
<TextBlock Name="tbEmpfAnsprechpartner" Text="Ansprechpartner" FontSize="14" FontWeight="Bold"/>
<TextBox x:Name="txtEmpfAnsprechpartner" FontSize="12" IsEnabled="False" Width="150" Margin="50,0,0,0"/>
</StackPanel>
<StackPanel x:Name="pnlEmpfMail" Grid.Column="0" Grid.Row="7" Margin="0,10,0,0" Orientation="Horizontal">
<TextBlock Name="tbEmpfMail" Text="Mailadresse" FontSize="14" FontWeight="Bold"/>
<TextBox x:Name="txtEmpfMail" FontSize="12" IsEnabled="False" Width="150" Margin="73,0,0,0"/>
</StackPanel>
<StackPanel x:Name="pnlGap2" Grid.Column="0" Grid.Row="8" Margin="0,10,0,0" Orientation="Horizontal">
</StackPanel>
<StackPanel x:Name="pnlAnlieferung" Grid.Column="0" Grid.Row="9" Margin="0,10,0,0" Orientation="Horizontal">
<TextBlock Name="tbAnlieferung" Text="Anlieferung" FontSize="14" FontWeight="Bold"/>
<ComboBox x:Name="cboxAnlieferung" FontSize="12" Width="150" Margin="77,0,0,0" Loaded="ComboBoxAnlieferung_Loaded" SelectionChanged="ComboBoxAnlieferung_Changed"/>
</StackPanel>
<StackPanel x:Name="pnlBauherr" Grid.Column="0" Grid.Row="10" Margin="0,10,0,0" Orientation="Horizontal">
<TextBlock Name="tbBauherr" FontSize="14" FontWeight="Bold"/>
<ComboBox x:Name="cboxAdressat" FontSize="12" IsEnabled="False" Width="200" Margin="135,0,0,0" DropDownClosed="CboxAdressat_DropDownClosed"/>
</StackPanel>
<StackPanel x:Name="pnlAdresse" Grid.Column="0" Grid.Row="11" Margin="0,10,0,0" Orientation="Horizontal">
<TextBlock Name="tbAdresse" FontSize="14" FontWeight="Bold" Text="Adresse"/>
<TextBox x:Name="txtAdresse" FontSize="12" IsEnabled="False" Width="150" Margin="93,0,0,0"/>
</StackPanel>
<StackPanel x:Name="pnlPlzOrt" Grid.Column="0" Grid.Row="12" Margin="0,10,0,0" Orientation="Horizontal">
<TextBlock Name="tbPlzOrt" FontSize="14" FontWeight="Bold"/>
<TextBox x:Name="txtPlzOrt" FontSize="12" IsEnabled="False" Width="150" Margin="135,0,0,0"/>
</StackPanel>
<StackPanel x:Name="pnlGap3" Grid.Column="0" Grid.Row="13" Margin="0,10,0,0" Orientation="Horizontal">
</StackPanel>
<StackPanel x:Name="pnlAnsprechpartnerOrt" Grid.Column="0" Grid.Row="14" Margin="0,10,0,0" Orientation="Horizontal">
<TextBlock Name="tbAnsprechpartnerOrt" FontSize="14" FontWeight="Bold" Text="Ansprechpartner vor Ort/Telefon"/>
<TextBox x:Name="txtAnsprechpartnerOrt" FontSize="12" Width="190" Margin="50,0,0,0" AcceptsReturn="False"/>
<Button x:Name="btnKontakt" Content="Kontakt auswählen" FontSize="12" Click="btnKontakt_Click" />
</StackPanel>
<StackPanel x:Name="pnlBemerkung" Grid.Column="0" Grid.Row="14" Margin="0,10,0,0" Orientation="Horizontal">
<TextBlock Name="tbBemerkung" FontSize="14" FontWeight="Bold" Text="Bemerkung"/>
<TextBox x:Name="txtBemerkung" FontSize="12" Width="250" Height="40" Margin="76,0,0,0" AcceptsReturn="False"/>
</StackPanel>
<StackPanel x:Name="pnlLiefertermin" Grid.Column="0" Grid.Row="15" Margin="0,10,0,0" Orientation="Horizontal">
<TextBlock Name="tbLiefertermin" FontSize="14" FontWeight="Bold" Text="Liefertermin"/>
<DatePicker x:Name="calLiefertermin" FontSize="12" Width="160" Margin="75,0,0,0" IsTodayHighlighted="true"/>
</StackPanel>
</StackPanel>
<!--rechts-->
<StackPanel Grid.Column="1" Margin="0,25,25,0" x:Name="rightStPnl">
<StackPanel x:Name="pnlLuxLogo" Grid.Column="1" Grid.Row="0" Margin="0,10,0,0" Orientation="Vertical">
<Image Source="Z:\SchaeferT\Projekte\Haustechnik\Nachbestellungen\Nachbestellungen\LuxLogo.png" Width="200" Height="30" HorizontalAlignment="Left"/>
</StackPanel>
<StackPanel x:Name="pnlFirma" Grid.Column="1" Grid.Row="1" Margin="0,27,0,0" Orientation="Vertical">
<TextBlock x:Name="tbFirma" FontSize="12" Text="Lux Projektmanagement GmbH & Co. KG"/>
</StackPanel>
<StackPanel x:Name="pnlFirmaAnschrift" Grid.Column="1" Grid.Row="2" Margin="0,10,0,0" Orientation="Vertical">
<TextBlock x:Name="tbFirmaAnschrift" FontSize="12" Text="Pleinfelder Straße 64"/>
</StackPanel>
<StackPanel x:Name="pnlFirmaPlzOrt" Grid.Column="1" Grid.Row="3" Margin="0,10,0,0" Orientation="Vertical">
<TextBlock x:Name="tbFirmaPlzOrt" FontSize="12" Text="91166 Georgensgmünd"/>
</StackPanel>
<StackPanel x:Name="pnlRightGap1" Grid.Column="1" Grid.Row="4" Margin="0,10,0,0" Orientation="Horizontal">
</StackPanel>
<StackPanel x:Name="pnlBearbeiter" Grid.Column="1" Grid.Row="5" Margin="0,10,0,0" Orientation="Horizontal">
<TextBlock Name="tbBearbeiter" FontSize="14" FontWeight="Bold" Text="Bearbeiter"/>
<ComboBox x:Name="cboxBearbeiter" FontSize="12" Width="150" Margin="30,0,0,0" Loaded="ComboBoxBearbeiter_Loaded" SelectionChanged="ComboBoxBearbeiter_Changed"/>
</StackPanel>
<StackPanel x:Name="pnlBearbeiterTel" Grid.Column="0" Grid.Row="6" Margin="0,10,0,0" Orientation="Horizontal">
<TextBlock Name="tbBearbeiterTel" FontSize="14" FontWeight="Bold" Text="Telefon"/>
<TextBox x:Name="txtBearbeiterTel" FontSize="12" IsEnabled="False" Width="150" Margin="45,0,0,0"/>
</StackPanel>
<StackPanel x:Name="pnlBearbeiterMail" Grid.Column="0" Grid.Row="7" Margin="0,10,0,0" Orientation="Horizontal">
<TextBlock Name="tbBearbeiterMail" FontSize="14" FontWeight="Bold" Text="Mail"/>
<TextBox x:Name="txtBearbeiterMail" FontSize="12" IsEnabled="False" Width="150" Margin="62,0,0,0"/>
</StackPanel>
<StackPanel x:Name="pnlBestelldatum" Grid.Column="0" Grid.Row="8" Margin="0,10,0,0" Orientation="Horizontal">
<TextBlock Name="tbBestelldatum" FontSize="14" FontWeight="Bold" Text="Best.-Datum"/>
<DatePicker x:Name="calBestelldatum" FontSize="12" Width="200" Margin="19,0,0,0" IsTodayHighlighted="true"/>
</StackPanel>
<StackPanel x:Name="pnlRightGap2" Grid.Column="1" Grid.Row="9" Margin="0,10,0,0" Orientation="Horizontal">
</StackPanel>
<StackPanel x:Name="pnlRightGap3" Grid.Column="1" Grid.Row="10" Margin="0,10,0,0" Orientation="Horizontal">
</StackPanel>
<StackPanel x:Name="pnlHinweis" Grid.Column="1" Grid.Row="11" Orientation="Vertical">
<TextBlock x:Name="tbHinweis" FontSize="12">
<Run Text=" Bitte geben sie auf ihren Dokumenten immer folgende Informationen an:
• Name des Bauvorhabens
• HV-Nummer und/oder Kostenstelle
• Name des Bestellers
• Abholer (nur bei Abholungen)
Entsprechende Angaben sind in dieser Bestellung fett/kursiv markiert. "/>
<Run FontFamily="Verdana" FontSize="11" Text="Rechnungen mit unvollständigen Angaben müssen wir ab dem 01.12.2013 ungebucht an sie zurücksenden. "/>
</TextBlock>
</StackPanel>
<StackPanel x:Name="pnlProjektleiter" Grid.Column="0" Grid.Row="14" Margin="0,10,0,0" Orientation="Horizontal">
<TextBlock Name="tbProjektleiter" FontSize="14" FontWeight="Bold" Text="Projektleiter"/>
<TextBox x:Name="txtProjektleiter" Text="{Binding Projektleiter, Mode=OneWay}" FontSize="12" IsEnabled="False" Width="225" Margin="50,0,0,0" AcceptsReturn="False"/>
</StackPanel>
</StackPanel>
<!-- unten -->
<DataGrid x:Name="dgArtikel" ItemsSource="{Binding Artikel}" Margin="5" Grid.Row="1" Grid.ColumnSpan="2"
SelectionMode="Single" SelectionUnit="Cell" IsReadOnly="False"
CanUserAddRows="True" CanUserDeleteRows="True" AutoGenerateColumns="False"
BorderBrush="Black" BorderThickness="2" RowHeight="30" FontFamily="Arial Narrow" FontSize="18"
LostFocus="DgArtikel_LostFocus" GotFocus="DgArtikel_GotFocus">
<!-- Style Column Headers -->
<DataGrid.Resources>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="Foreground" Value="#FFFFFF"/>
<Setter Property="Background" Value="#DD002C"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="BorderThickness" Value="0,0,1,2"/>
<Setter Property="BorderBrush" Value="Black"/>
<Setter Property="FontSize" Value="18"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="Height" Value="30"/>
</Style>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn Header="Pos" Binding="{Binding Pos}"/>
<DataGridTextColumn Header="Artikelbezeichnung" Binding="{Binding Artikelbezeichnung}"/>
<DataGridTextColumn Header="Artikelnummer" Binding="{Binding Artikelnummer}"/>
<DataGridTextColumn Header="Einheit" Binding="{Binding Einheit}"/>
<DataGridTextColumn Header="Menge" Binding="{Binding Menge}"/>
<DataGridTextColumn Header="Einzelpreis" Binding="{Binding Einzelpreis}"/>
<DataGridTextColumn Header="Gesamtpreis" Binding="{Binding Gesamtpreis}"/>
<DataGridComboBoxColumn Header="Anforderungsgrund" x:Name="dgcbAnf" ItemsSource="{Binding Anforderungsgrund}"/>
<DataGridTextColumn Header="Anforderungsnr" Binding="{Binding Anforderungsnr}"/>
<DataGridTextColumn Header="Anforderer" Binding="{Binding Anforderer}"/>
<DataGridTextColumn Header="Bemerkungen" Binding="{Binding Bemerkungen}"/>
</DataGrid.Columns>
</DataGrid>
<Border x:Name="borderBtnArtikel" Grid.Row="2" Grid.Column="0" Margin="25,0,0,0" CornerRadius="10" BorderBrush="Black" BorderThickness="2" Background="PaleVioletRed" HorizontalAlignment="Left">
<Button Name="btnArtikel" Margin="3,0,3,0" Content="Artikel suchen" Height="30" FontWeight="Bold" FontSize="15" Background="PaleVioletRed" Click="BtnArtikel_Click" VerticalAlignment="Top" BorderThickness="0" BorderBrush="PaleVioletRed"></Button>
</Border>
<Border x:Name="borderBtnVorhanden" Grid.Row="2" Grid.Column="0" Margin="0,0,25,0" CornerRadius="10" BorderBrush="Black" BorderThickness="2" Background="Yellow" HorizontalAlignment="Right">
<Button Name="btnVorhanden" Margin="3,0,3,0" Content="Vorhandene Nb Aufrufen" Height="30" FontWeight="Bold" FontSize="15" Background="Yellow" Click="BtnVorhanden_Click" VerticalAlignment="Top" BorderThickness="0" BorderBrush="Yellow"></Button>
</Border>
<Border Grid.Row="2" Grid.Column="1" CornerRadius="10" BorderBrush="Black" BorderThickness="2" Background="Green" Margin="25,0,0,0" HorizontalAlignment="Left">
<Button Name="btnSpeichern" Margin="3,0,3,0" Content="Neue Nb Speichern"
BorderThickness="0" BorderBrush="Green"
Height="30" FontWeight="Bold" FontSize="15"
Background="Green"
VerticalAlignment="Top"
Command="{Binding SaveNb}"
>
</Button>
<!-- Click="BtnSpeichern_Click" -->
</Border>
<Border Grid.Row="2" Grid.Column="1" CornerRadius="10" BorderBrush="Black" BorderThickness="2" Background="Orange" HorizontalAlignment="Right" Margin="0,0,25,0">
<Button Name="btnOutlook" Margin="3,0,3,0" Content="Nb per Outlook versenden" Height="30" BorderThickness="0" BorderBrush="Orange" FontWeight="Bold" FontSize="15" Background="Orange" Click="BtnOutlook_Click"></Button>
</Border>
</Grid>
如您所见,Outlook 操作(橙色按钮)在非常糟糕的设计中仍然与 CodeBehind 中的 BtnOutlook_Click 事件处理程序紧密耦合。因此,在将 Green SaveNb Button 正确绑定到上述 4 个方法之后,我将继续使用此按钮和其他按钮,将它们与 CodeBehind 一个一个解耦,以便根据标准约定获得更好的可重用性和灵活性代码。
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<object>(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
或事件。视图本身知道它何时打开或可见,然后应该开始与视图模型通信。
编辑
查看 C# 代码:
public partial class addReorder : System.Windows.Window
{
public addReorder(string hvId)
{
InitializeComponent();
this.DataContext = new addReorderViewModel(hvId);
}
}
查看模型:
public class addReorderViewModel
{
public addReorderViewModel(string hvId)
{
InitializeReorderModel(hvId);
this.ArtikelList = new ObservableCollection<Artikel>();
//Die Anforderungscollection wird befüllt
IAnforderungsgrund anfgruende = new Anforderungsgrund();
this.AnfCollection = anfgruende.ListeAnforderungen();
}
public InitializeReorderModel(string hvId)
{
this.Nachbest = new ReorderModel();
//HV, BV, Projektleiter und Bauleiter holen
var dbOracle = new Datenbank();
this.Nachbest.BV = dbOracle.GetBauvorhaben(hv);
this.Nachbest.Hv = hv;
this.Nachbest.Bauleiter = dbOracle.GetBauleiter(hv);
this.Nachbest.Projektleiter = dbOracle.GetProjektleiter(hv);
}
private void ExecuteMethods(object param)
{
var mongo = DbConn(); //Connection to MongoDB
var artikel = this.ArtikelList; //returns ObservableCollection<ArtikelModel>
var reorder = this.Nachbest; //returns ReorderModel
Insert(mongo, artikel, reorder); //inserts new reorder into the MongoDB database (one reorder has multiple articles(artikel))
}
public ICommand SaveNb => new DelegateCommand<object>(ExecuteMethods, CanExecuteMethods);
public ReorderViewModel Nachbest {get; set;}
public ObservableCollection<string> AnfCollection {get; set;}
public ObservableCollection<Artikel> ArtikelList {get; set;}
}
XAML 片段:
<!-- links -->
<StackPanel x:Name="leftStPnl" DataContext="{Binding Nachbest}" ... >
<StackPanel x:Name="pnlBv" Grid.Column="0" Grid.Row="1" Margin="0,10,0,0" Orientation="Horizontal">
<TextBlock Name="tbBv" Text="Bauvorhaben" DockPanel.Dock="Left" FontSize="14" FontWeight="Bold"/>
<TextBox Name="txtBv" Text="{Binding Bv }" />
</StackPanel>
<StackPanel x:Name="pnlHv" Grid.Column="0" Grid.Row="2" Margin="0,10,0,0" Orientation="Horizontal">
<TextBlock Name="tbHv" Grid.Column="0" Text="HV-Nummer" FontSize="14" FontWeight="Bold"/>
<TextBox x:Name="txtbHv" Text="{Binding Hv}"/>
</StackPanel>
...
</StackPanel>
<!-- rechts -->
<StackPanel x:Name="rightStPnl" DataContext="{Binding Nachbest}" ... >
...
</StackPanel>
<DataGrid x:Name="dgArtikel" ItemsSource="{Binding ArtikelList}" ... >
...
</DataGrid>