views:

503

answers:

2

Hi,

I have a WPFToolkit-datagrid and a View-model class with a property - "SelectedGridItems" How do I bind selectedItem property of WPFToolkit-Datagrid to my viewmodel property ("SelectedGridItems") ?

+1  A: 

This is code for WPF4's DataGrid, I don't have access to Toolkit at the moment, but I doubt it is different.

For binding a single row in a datagrid:

<DataGrid ItemsSource="{Binding ViewModelCollectionProperty}"
SelectedItem="{Binding Path=ViewModelProperty}">

</DataGrid>

To bind multiple selected rows, your best bet is probably to create an attached property which maintains a collection of selected items which can then be data bound to viewmodel.

EDIT -- added link below

See here for article about creating an attached property doing very similar to what you want: http://alexshed.spaces.live.com/Blog/cns!71C72270309CE838!149.entry

Tendlon
I am following MVVM pattern...so cant write anything in view-codebehind file. Can you tell me 1. Can I have attached property to a WPFToolkit control.2. Can I do attach property in XAMl(not using RergisterAttached in codebehind)
Anish
Anish, take a look at the link I edited in to the post.
Tendlon
+1  A: 

Here is an attached property that hooks to the SelectionChanged event of the ListBox and populates a list of selected items to the ViewModel. You can simply change "ListBox" to "DataGrid".

http://marlongrech.wordpress.com/2009/06/02/sync-multi-select-listbox-with-viewmodel/

Edit: Adding source code for DataGrid version...

/// <summary>
/// Attached property that stores the selected items of a DataGrid
/// </summary>
public static class DataGridService
{
   #region SelectedItems

   /// <summary>
   /// SelectedItems Attached Dependency Property
   /// </summary>
   public static readonly DependencyProperty SelectedItemsProperty = DependencyProperty.RegisterAttached(
       "SelectedItems", 
       typeof(IList), 
       typeof(DataGridService),
       new FrameworkPropertyMetadata((IList)null, new PropertyChangedCallback(OnSelectedItemsChanged)));

   /// <summary>
   /// Gets the SelectedItems property.
   /// </summary>
   /// <param name="d"><see cref="DependencyObject"/> to get the property from</param>
   /// <returns>The value of the SelectedItems property</returns>
   public static IList GetSelectedItems(DependencyObject d)
   {
      return (IList)d.GetValue(SelectedItemsProperty);
   }

   /// <summary>
   /// Sets the SelectedItems property.
   /// </summary>
   /// <param name="d"><see cref="DependencyObject"/> to set the property on</param>
   /// <param name="value">value of the property</param>
   public static void SetSelectedItems(DependencyObject d, IList value)
   {
      d.SetValue(SelectedItemsProperty, value);
   }

   /// <summary>
   /// Handles changes to the SelectedItems property.
   /// </summary>
   /// <param name="d"><see cref="DependencyObject"/> that fired the event</param>
   /// <param name="e">A <see cref="DependencyPropertyChangedEventArgs"/> that contains the event data.</param>
   private static void OnSelectedItemsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
   {
      var grid = (DataGrid)d;
      ReSetSelectedItems(grid);
      grid.SelectionChanged += delegate
      {
         ReSetSelectedItems(grid);
      };
   }

   /// <summary>
   /// Sets the selected items collection for the specified <see cref="DataGrid"/>
   /// </summary>
   /// <param name="grid"><see cref="DataGrid"/> to use for setting the selected items</param>
   private static void ReSetSelectedItems(DataGrid grid)
   {
      IList selectedItems = GetSelectedItems(grid);
      selectedItems.Clear();
      if (grid.SelectedItems != null)
      {
         foreach (var item in grid.SelectedItems)
         {
            selectedItems.Add(item);
         }
      }
   }

   #endregion
}

In the XAML:

<tk:DataGrid ... local:DataGridService.SelectedItems="{Binding Path=MyCollection}" SelectionMode="Extended">

"MyCollection" should be an ObservableCollection in your ViewModel.

John Myczek
Hi,This is very useful link...but one issue i have met with is DataGrid do not have a property named "selectedItems"...it s only having a property "selecteditem".Can we do something link attached property to overcome the same?If so Can I have it in mvvm model...i mean attached property in view-model ?
Anish
The DataGrid does have a SelectedItems property: http://msdn.microsoft.com/en-us/library/system.windows.controls.datagrid.selecteditems(VS.95).aspx I have updated my answer to include the source code to the DataGrid version of the property.
John Myczek
I have checked this ...but issue is "OnSelectedItemsChanged" is not getting called. :(
Anish
Hi Thankkkssssssss Alot ...I have implemented it...Very much thank full to .....if i dint get tat i wud have got screwed :(
Anish
No problem. The issue with "OnSelectedItemsChanged is not getting called", is probably just a case of a confusing method name. That method does not get called when the DataGrid selection changes, it gets called when the SelectedItems attached property changes. ReSetSelectedItems should get called when the DataGridSelection changes.
John Myczek