Gerald Gonzales
Gerald Gonzales

Reputation: 533

ICommand not working in Silverlight User control

I have a UserControlBase with a grid. The grid contains a column with an Action.

<sdk:DataGridTemplateColumn Header="Action">
    <sdk:DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <StackPanel>
                 <Button Style="{StaticResource DataGridButton}"  Command="{Binding Source={StaticResource NewsViewModel}, Path=ModifyNewsCommand}" Content="Modify" />
             </StackPanel>
         </DataTemplate>
     </sdk:DataGridTemplateColumn.CellTemplate>
 </sdk:DataGridTemplateColumn>

My problem is with my Command. It is throwing me Technical Error which is my first problem, I don't know how to make this application throw me the real error message.

In the code behind of my user control I registered the events:

protected void RegisterMessages()
{
    Messenger.Default.Register<string>(this, "NewNewsBtn_Click", NewNewsBtn_Click);
    Messenger.Default.Register<string>(this, "ModifyNewsBtn_Click", ModifyNewsBtn_Click);
}

And in my constructor:

public NewsWindow(int underlyingId)
{
    InitializeComponent();
    this.RegisterMessages();
    viewModel = new NewsViewModel(underlyingId);
    ucNewsPanel.DataContext = viewModel;
}

My view model (NewsViewModel)

public ICommand ModifyNewsCommand
{
    get
    {
        return new RelayCommand<string>(e =>
        {
            Messenger.Default.Send(string.Empty, "ModifyNewsBtn_Click");
        });
    }
}

What's weird here is that my NewNewsBtn is working, while my ModifyNewsBtn is not.

This button is outside the grid so it might make a difference on why it is working.

<Button x:Name="NewNewsBtn" MaxHeight="50" MaxWidth="100" Command="{Binding Path=NewNewsCommand}" Content="Add New" />

Upvotes: 0

Views: 63

Answers (2)

Martin
Martin

Reputation: 6172

Your DataGrid will be bound to some collection, having a row per each item. Now the item is the DataContext for a row. What you need to do is bind your "Modify"-button to the parent DataContext. If you are using silverlight5 you can use an AncestorBinding:

<Button
    Content="Modify"
    Command="{Binding
        Path=DataContext.ModifyNewsCommand,
        RelativeSource={RelativeSource AncestorType=UserControl}}"/>

Upvotes: 1

StepUp
StepUp

Reputation: 38199

Your syntax looks okay:

<Button Style="{StaticResource DataGridButton}" Content="Modify" 
  Command="{Binding Source={StaticResource NewsViewModel}, Path=ModifyNewsCommand}"/>

But you set your viewModel in code. Am I right that you create StaticResource in XAML? If it is, then just delete setting DataContext from code-behind cause the following row Command="{Binding Source={StaticResource NewsViewModel}, Path=ModifyNewsCommand}" will see in the another instance of your viewModel. (cause you've create two instances of NewsViewModel as a StaticResource and in code-behind)

Update:
I needed the DataContext in code behind as I am passing a parameter to my view model. Any way I can do that if I removed it from code behind?
Then you should delete StaticResource from Binding of Command:

<Button Style="{StaticResource DataGridButton}" Command="{Binding ModifyNewsCommand}" 
                                                                    Content="Modify"/>

Cause you are referencing to another instance of NewsViewModel.

Upvotes: 0

Related Questions