views:

269

answers:

2

I'm using the MVVM pattern. I've bound my items and I want to only show the edit button when a row is selected in the datagrid. It appears to be possible with triggers in WPF but we don't have triggers in Silverlight. I tried a TemplatedParent binding but I'm not sure what the TemplatedParent is in this case. We don't have RelativeSource ancestor in Silverlight either. At this point I'm going to look at a solution using the code behind...

<data:DataGrid.Columns>
   <data:DataGridTemplateColumn IsReadOnly="True" Header="Name" Width="300">
      <data:DataGridTemplateColumn.CellTemplate>
         <DataTemplate>
            <Grid>
               <TextBlock x:Name="textBlock" Text="{Binding Name, Mode=OneWay}" VerticalAlignment="Center" Margin="4,4,0,4"/>
               <Button  Margin="1,1,4,1" HorizontalAlignment="Right" VerticalAlignment="Center" Padding="7,4" Content="Edit" />
            </Grid>
         </DataTemplate>
       </data:DataGridTemplateColumn.CellTemplate>
   </data:DataGridTemplateColumn>
</data:DataGrid.Columns>
+1  A: 

There are a couple ways you could do this in silverlight, although I don't think any of them can be pure XAML solutions. With MVVM, you then create property in your view model that you bind to the SelectedItem property of the DataGrid. From there, there are two differnt options:

  1. If the individual items in the DataGird are themselves other view models, then you can give them a property like "IsEditable" and bind it to the visibility of the button. When the SelectedItem fo the parent ViewModel changes, go and update the IsEditable property of all the child viewmodels
  2. If you dont have child view models, you can handle the loaded event of the Edit button. In the code behind, bind the visibility of the button to the selecteditem property in your view model, but also set up a binding converter that takes in the original bound item as a converter parameter. In the converter, you can check if the selected item is equal to the originally bound item
Jacob Adams
I went with something similar to option 1. I added an IsSelected property onto my item viewmodel (I have an PagedCollectionView of items). I used the SelectionChanged event to iterate through the e.RemovedItems and cleared the selected flag. Same for the e.AddedItems. I may look at adding a SelectedItem to my main viewmodel. If anyone goes that route I think the easiest way would be to clear the flag in the SelectedItem's setter on the old item and set the flag on the new SelectedItem.
miketrash
A: 

If only Silverlight had a RelativeSource FindAncestor binding...

One kind-of hacky idea I could suggest would be to put your editing controls into a RowDetailsTemplate on the DataGrid itself, then set the RowDetailsVisibilityMode to VisibleWhenSelected.

It might not be what you're after look-wise, but it probably "solves" your particular use-case.

If it doesn't, then I'd probably violate MVVM here (very carefully). Usually DataGrids are the bastard child edge case; they almost all need some variety of code-behind.

JerKimball
I considered using RowDetails but you are right..the look is not what I'm going for. Nice suggestion though.
miketrash