Search code examples
c#wpfxamldata-bindingmaterial-design-in-xaml

WPF Command binding in button inside a materialDesign dialog


Im new to WPF and material desing. And im trying to make a dialog for a confirmation of a button, but when i bind the command and press the button it never gets to the method.

The dialog is made in a dynamicly populated listBox.

Window

   <ListBox  Height="585" 
         Name="NoteList"
         ScrollViewer.CanContentScroll="True"
         ScrollViewer.VerticalScrollBarVisibility="Visible" 
         ScrollViewer.HorizontalScrollBarVisibility="Disabled"   
         ItemsSource="{Binding dtoRecetas}" Grid.Row="1">

        <ListBox.ItemTemplate>
            <DataTemplate>

               <!--VERSION CARTAS-->
               <materialDesign:Card Style="{StaticResource cardsRecetas}" >
                  <Grid>
                      <Grid.RowDefinitions>
                           <RowDefinition Height="150"/>
                            <RowDefinition Height="170"/>
                       </Grid.RowDefinitions>

                       <StackPanel Orientation="Horizontal" HorizontalAlignment="Right">

                          <!-- DIALOGO DE ELIMINAR RECETA-->
                          <materialDesign:DialogHost  CloseOnClickAway="True" >
                             <materialDesign:DialogHost.DialogContent>
                                 <StackPanel Margin="16">
                                    <TextBlock>Deseas eliminar esta receta</TextBlock>

                                    <StackPanel Orientation="Horizontal"  HorizontalAlignment="Right">

                                       <Button Style="{StaticResource MaterialDesignFlatButton}"
                                                        IsDefault="True"
                                                        Margin="0 8 8 0"
                                                        Command="{Binding Path=comandoDeleteReceta}"
                                                        CommandParameter="{Binding idReceta}">
                                                    Aceptar
                                       </Button>

                                      <Button Style="{StaticResource MaterialDesignFlatButton}"
                                                        Margin="0 8 8 0"
                                                        Command="{x:Static materialDesign:DialogHost.CloseDialogCommand}">
                                              Cancelar
                                       </Button>
                                     </StackPanel>

                                    </StackPanel>
                              </materialDesign:DialogHost.DialogContent>

                             <Button x:Name="btnDeleteReceta" Style="{StaticResource btnDeleteReceta}" 
                                        Tag="{Binding idReceta}"
                                        Command="{x:Static materialDesign:DialogHost.OpenDialogCommand}">

                                   <materialDesign:PackIcon Kind="RemoveCircle" />

                                </Button>
                          </materialDesign:DialogHost>

                       </StackPanel>


                    </Grid>
                </materialDesign:Card>

            </DataTemplate>

            </ListBox.ItemTemplate>
            <ListBox.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel  ScrollViewer.VerticalScrollBarVisibility="Visible" ScrollViewer.HorizontalScrollBarVisibility="Disabled"  ></WrapPanel>
                </ItemsPanelTemplate>
            </ListBox.ItemsPanel>
        </ListBox>

ViewModel

 public class VerRecetasViewModel : BaseViewModel 
    {
        public Command comandoDeleteReceta { get; set; }
        public ObservableCollection<DTOReceta> dtoRecetas { get; set; }

        public VerRecetasViewModel()
        {
            RecetasController recController = new RecetasController();
            dtoRecetas = new ObservableCollection<DTOReceta>(recController.getAllRecetas());

            comandoDeleteReceta = new Command();
            comandoDeleteReceta.CanExecuteFunc = obj => true;
            comandoDeleteReceta.ExecuteFunc = deleteReceta;
        }



        public void deleteReceta(object parameter)
        {
            int idReceta = (int)parameter;
            RecetasController recController = new RecetasController();
            recController.deleteReceta(idReceta);
        }


    }

The desired behavior is that when they press "Aceptar" it gets to the "deleteReceta" method, but as right now it looks like is not finding the binded command. enter image description here

The command class is working and i use commands in other windows this way and it works, i think im losing the context from the dialog or creating it wrong. I tried this way and adding relative source to the binding, but i dont know what the ancestortype should be.

Thanks for the help.


Solution

  • I think it's a problem with the DataContext. So I would set the dataContext of the view like this : d:DataContext="{d:DesignInstance {x:Type vm:VerRecetasViewModel}}"

    and in the ListBox, bind the command on the button like this :

    Command="{Binding DataContext.comandoDeleteReceta, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}}"
    

    Hope this helps