timunix
timunix

Reputation: 629

How to use ICommand for executing multiple methods after Buttonclick

I have a lack of understanding how to use the ICommand inferface for executing multiple methods in a row. Ideally I would like to create a delegate that executes all of the following 4 methods by invoking it (but it doesn't have to be a delegate):

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 (excerpt):

<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>

Code Behind:

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

The ViewModel (need help here):

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

The ViewModel has a "hook" to the 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);
        }
    }

Questions:

  1. What do I have to do to make the buttonclick execute the above mentioned 4 methods?

  2. How do I add other buttonclick events (the view has about 5-10 buttons) into the ViewModel?

  3. How does the ViewModel know about the current View that is open?

The methods inside the 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);
         }   

This is the view design: enter image description here This is the datagrid inside the view design (dummy example) enter image description here

The GREEN BUTTON is the INSERT part I want to execute with the help of the ICommand interface, i.e. do the following after clicking:

  1. Connect to MongoDB

  2. Get me the observableCollection()

  3. Get me the ReorderModel instance

  4. Do the Insert into my database collection

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>

As you can see, the Outlook operation (orange button) is still tightly coupled in a very bad design with the BtnOutlook_Click event handler inside the CodeBehind. So after binding the Green SaveNb Button properly to those 4 methods mentioned I would go on with this button and other buttons, decoupling them one by one from the CodeBehind for better reusable and flexible code according to standard conventions.

Upvotes: 1

Views: 1244

Answers (2)

BionicCode
BionicCode

Reputation: 28988

  1. Since you are using DelegateCommand you just have to initialize it properly:

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. For every other button that communicates with the view model use ICommand too. You just define new ICommand properties with new Execute and CanExecute delegates.

  2. The view model should never know anything about the view. It should never operate on the view. The only way data is send to the view is to use Binding or events. The view itself knows when it's opened or visible and should then start to communicate with the view model.

Edit

View C# code:

public partial class addReorder : System.Windows.Window
{
    public addReorder(string hvId) 
    {
      InitializeComponent();
      this.DataContext = new addReorderViewModel(hvId);
    }
}

View model:

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 snippet:

<!-- 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>

Upvotes: 2

Nachiappan Kumarappan
Nachiappan Kumarappan

Reputation: 291

Command in WPF is to execute one method when a command is generated from UI (button click). Now you have 4 methods to be executed on a command. So create one method (or Action) that contains the four method calls and bind that method to the command.

In the constructor of the view model add some thing like below

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

Upvotes: 0

Related Questions