Command binding inside a DataGridTemplateColumn
Asked Answered
A

4

6

I am working on a Silverlight application which makes an extensive use of Prism, the MVVM pattern and MEF. For several reasons, I have chosen to follow a View-first approach.

In one of the Views there is a DataGrid, and one of the columns of this grid is a DataGridTemplateColumn, which has just a Button.

I'd like to define both a Command and a CommandParameter on the Button. The Command should be a DelegateCommand of the ViewModel. CommandParameter should be the SelectedItems list coming straight out of the dataGrid.

I've tried several approaches to do this, but either Command or CommandParameter are null.

It follows the code that I originally wrote:

<sdk:DataGridTemplateColumn>
    <sdk:DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <Button Width="15" Height="15" Content=">" 
                    Command="{Binding UpdateSearchParametersCommand}" 
                    CommandParameter="{Binding SelectedItems, ElementName=dataGrid}">
        </DataTemplate>
    </sdk:DataGridTemplateColumn.CellTemplate>
</sdk:DataGridTemplateColumn>

Could someone advice me on what the best way to go about it is?

Thanks in advance, Gianluca.

Aquaplane answered 5/7, 2011 at 13:7 Comment(0)
A
0

Many of you tried to help me out on this. Thank you for that. Unfortunately the provided answers were mostly relative to WPF.

Here is how I've solved the problem:

<helpers:BindingHelper.Binding>
<helpers:BindingList>
     <helpers:RelativeSourceBinding TargetProperty="Command" Path="DataContext.ToggleDataArchiveInheritanceCommand" RelativeMode="FindAncestor" AncestorType="ChildWindow" />
</helpers:BindingList>
</helpers:BindingHelper.Binding>

Ok, this comes from another point of the same application, but the principle is the same. If a binding is defined inside a , the only way you have in Silverlight to reach out other elements that normally would be out-of-scope (as they are not part of the DataTemplate) is to walk through the xaml object tree. That's what the BindingHelper does.

Posting here as I hope the information will be useful to someone else.

Cheers,

Gianluca

Aquaplane answered 21/7, 2011 at 15:45 Comment(2)
Ciao Gianluca, thx for posting this...I'm trying to do this same thing, but not sure what "BindingHelper" is. Is there more code that goes with this, or is BindingHelper something in Silverlight?Kennard
Hi Joe. You are right, there is more code, which is quite simple though and which I have described in words earlier, in this same post. I'll need to look for the source code I was working on the 2011 in order to copy&paste the helper class that I had created at the time. cheers for now. g.Aquaplane
O
12

Your current binding is pointing to DataGridRowItem.UpdateSearchParametersCommand. You need to change it to point to DataGrid.DataContext.UpdateSearchParametersCommand

<sdk:DataGrid x:Name=dataGrid>
    <sdk:DataGridTemplateColumn>
        <sdk:DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <Button Width="15" Height="15" Content=">" 
                        Command="{Binding DataContext.UpdateSearchParametersCommand, ElementName=dataGrid}" 
                        CommandParameter="{Binding SelectedItems, ElementName=dataGrid}">
            </DataTemplate>
        </sdk:DataGridTemplateColumn.CellTemplate>
    </sdk:DataGridTemplateColumn>
</sdk:DataGrid>
Oyster answered 5/7, 2011 at 13:47 Comment(0)
P
2

If you bind your DataGrid using ItemsSource, then Command and CommandParameter binding is associated to the current item - the way you've written.

You should use alternative source in this case. Command should be binded to the DataContext.UpdateSearchParametersCommand and CommandParameter - to DataContext.SelectedItems.

In your case neither UpdateSearchParametersCommand, nor SelectedItems cannot be found in the binded item.

UPDATED

Be sure to set the right type for ancestor. I've set it to window, but maybe you are using UserControl.

<sdk:DataGridTemplateColumn>
<sdk:DataGridTemplateColumn.CellTemplate>
    <DataTemplate>
        <Button Width="15" Height="15" Content=">" 
                Command="{Binding Path=DataContext.UpdateSearchParametersCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" 
                CommandParameter="{Binding Path=DataContext.SelectedItems, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}">
    </DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>

Petaliferous answered 5/7, 2011 at 13:34 Comment(8)
Improve this answer by including the xaml that the button ought to have.Ankus
@Ankus Right you are.Petaliferous
@26071986: Thank you for your reply. However I've noticed that in your solution, you look for an Ancestor of type Window. I might be completely wrong, but as far as I know that's not supported in Silverlight. Is it correct?Aquaplane
@Gianluca Colucci Very probably. As an AncestorType you should put the type of your View, to which ViewModel binding is done. Then everything should be fine.Petaliferous
@Petaliferous RelativeSource only works with Self and TemplatedParent in Silverlight 4. You'll need to use ElementName insteadOyster
@26071986: I am afraid but I have to confirm what Rachel has already stated: in Silverlight there is no full support for RelativeSource and only Self and TemplatedParent can be used.Aquaplane
@Rachel: Unfortunately there are several well-documented problems in using ElementName and DataTemplates. Primarily they are related to the scope.Aquaplane
@26071986: Yes :) I've realized that. I am going to post my solution to the problem.Aquaplane
P
1

In silverlight 5 you can do this

<Button Command="{Binding Path=DataContext.PreviewPublishCommand, RelativeSource={RelativeSource AncestorType=controls:ChildWindow}}" Content="Publish" />

Just adjust AncestorType to be whatever your top level element is (UserControl, ChildWindow, etc).

Promising answered 9/10, 2012 at 20:13 Comment(0)
A
0

Many of you tried to help me out on this. Thank you for that. Unfortunately the provided answers were mostly relative to WPF.

Here is how I've solved the problem:

<helpers:BindingHelper.Binding>
<helpers:BindingList>
     <helpers:RelativeSourceBinding TargetProperty="Command" Path="DataContext.ToggleDataArchiveInheritanceCommand" RelativeMode="FindAncestor" AncestorType="ChildWindow" />
</helpers:BindingList>
</helpers:BindingHelper.Binding>

Ok, this comes from another point of the same application, but the principle is the same. If a binding is defined inside a , the only way you have in Silverlight to reach out other elements that normally would be out-of-scope (as they are not part of the DataTemplate) is to walk through the xaml object tree. That's what the BindingHelper does.

Posting here as I hope the information will be useful to someone else.

Cheers,

Gianluca

Aquaplane answered 21/7, 2011 at 15:45 Comment(2)
Ciao Gianluca, thx for posting this...I'm trying to do this same thing, but not sure what "BindingHelper" is. Is there more code that goes with this, or is BindingHelper something in Silverlight?Kennard
Hi Joe. You are right, there is more code, which is quite simple though and which I have described in words earlier, in this same post. I'll need to look for the source code I was working on the 2011 in order to copy&paste the helper class that I had created at the time. cheers for now. g.Aquaplane

© 2022 - 2024 — McMap. All rights reserved.