单击按钮后如何使用命令执行多个方法

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

问题:

  1. 我要怎么做才能让buttonclick执行上面的 提到了4个方法?

  2. 如何将其他按钮单击事件(视图有大约 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);
         }   

这是视图设计: 这是视图设计中的数据网格(虚拟示例)

绿色按钮是我想借助 ICommand 接口执行的插入部分,即点击后执行以下操作:

  1. 连接到 MongoDB

  2. 给我 observableCollection()

  3. 给我 ReorderModel 实例

  4. 插入我的数据库集合

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&#10;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 &amp; 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:&#10;&#10;
 • Name des Bauvorhabens&#10;
 • HV-Nummer und/oder Kostenstelle&#10;
 • Name des Bestellers&#10;
 • Abholer (nur bei Abholungen)&#10;&#10;
Entsprechende Angaben sind in dieser Bestellung fett/kursiv markiert.&#10;&#10;"/>
                <Run FontFamily="Verdana" FontSize="11" Text="Rechnungen mit unvollständigen Angaben müssen wir&#10; ab dem 01.12.2013 ungebucht an sie zurücksenden.&#10;"/>
            </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))
    });
}
  1. 由于您正在使用 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;
}
  1. 对于与视图模型通信的每个其他按钮也使用 ICommand。您只需使用新的 Execute 和 CanExecute 委托定义新的 ICommand 属性。

  2. 视图模型永远不会知道视图的任何信息。它永远不应该对视图进行操作。将数据发送到视图的唯一方法是使用 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>