1
votes

I am just getting started with WPF and MVVM and managed to bind my Datagrid to the list ProductList of my DataContext ViewModel Class. However, I am now trying to bind the buttons inside my DataGrid to some Commands of my DataContext Class.

<DataGrid x:Name="myDataGrid" ItemsSource="{Binding ProductsList}" x:FieldModifier="public" AutoGenerateColumns="False">
    <DataGrid.Columns>
        <DataGridTextColumn Header="No MAT" Binding="{Binding MATProductNumber}" Width="0.1*"/>
            <DataGridTextColumn Header="Format" Binding="{Binding tblFormat.FormatName}" Width="0.1*"/>
            <DataGridTextColumn Header="Nom produit" Binding="{Binding tblProduct.ProductName}" Width="0.1*"/>
            <DataGridTextColumn x:Name="productGradeHeader" Header="Grade" Binding="{Binding tblGrade.GradeName}" Width="0.1*"/>
            <DataGridTemplateColumn Width=".1*"           
                <DataGridTemplateColumn.HeaderTemplate> 
                     <DataTemplate>
                       <StackPanel Orientation="Horizontal">
                          <Button x:Name="leftArrowSearchButton" Command="{Binding PreviousPageCommand}" CommandParameter="1">
                            <materialDesign:PackIcon Kind="ArrowLeftThick" Width="25" Height="25" VerticalAlignment="Center"/>
                          </Button>
                          <Button x:Name="rightArrowSearchButton" Command="{Binding NextPageCommand}" CommandParameter="1">
                            <materialDesign:PackIcon Kind="ArrowRightThick" Width="25" Height="25" VerticalAlignment="Center"/>
                          </Button>
                       </StackPanel>
                     </DataTemplate>
               </DataGridTemplateColumn.HeaderTemplate>
           </DataGridTemplateColumn>
   </DataGrid.Columns>
</DataGrid>

This line right here is supposed to Bind to PreviousPageCommand in my Data context

<Button x:Name="leftArrowSearchButton" Command="{Binding PreviousPageCommand}" CommandParameter="1"  ToolTip="Voir la page précédente" Height="24" Width="53" Margin="0,0,20,0">

I have debugged and found out that it's not even calling the function. Therefore, I am almost certain that there is a problem with the binding.

It seems like my button is trying to Bind to an element of ProductsList. Is there a way of going back one level up? I have already tried binding my buttons to DataContext.PreviousPageCommand

Thanks in Advance!

Edit 1: Here is the code in the Backend as requested

 public ObservableCollection<tblMATProduct> ProductsList { get; set; }

 private void NextPageScrollCommand(string number)
 {
     Page++;
     navigate(Page, Size);
 }

 public void navigate(int page, int size)
 {
     var result = new ObservableCollection<tblMATProduct>(db.tblMATProduct.Include(s => s.tblGrade).Include(s => s.tblProduct).Include(s => s.tblFormat).OrderBy(s => s.MATProductID).Skip(page * size).Take(size).ToList());
     ProductsList = result;
 }

ProductsList is updating, I can see it in the debugger. It's only the UI that's not updating.

Edit 2: It's working fine now! Just added this line to my ProductsList setter:

set
        {
            SetProperty(ref _products, value);
        }
2
You can bind Source = mydatagrid.DataContext Path = PreviousPageCommand, basically binding to myDataGrid DataContext which is your ViewModel - iNCEPTiON_
It says it can't read myDataGrid even though I have set it as x:Name of my Datagrid, how else could I refer to it? - Randy Quackers
Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}, Path=DataContext.PreviousPageCommand}" - iNCEPTiON_
Previous page seems a bit of an odd command to be associated with a record in a datagrid. Previous page for the specific product? Anyhow. You'll also need to bind the selecteditem of your datagrid so the viewmodel knows which row the button was in when the user clicks. Or bind the datacontext of the button to the commandparameter. - Andy
Wow, now it's working. Can't thank you enough! If you want to post it as an answer, I will mark it as the solution - Randy Quackers

2 Answers

2
votes

As stated in my comment you need to bind to (ViewModel) Parent/Ancestor.DataContext

Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}, Path=DataContext.PreviousPageCommand}"

You'll also need to bind the SelectedItem of your DataGrid so the ViewModel knows which row the button was in when the user clicks. Or bind the DataContext of the button to the CommandParameter. like @Andy mentioned in the comment

1
votes

Hello you can do as follow:

{Binding DataContext.PreviousPageCommand, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}

But the binding will be update only when DataGrid.DataContext'll change, and not when DataContext.PreviousPageCommand'll change.