Selecting multiple records in DataGrid with Caliburn.Micro












4















I have a WPF application using Caliburn.Micro.



The DataGrid has an attribute SelectedItem="{Binding Path=SelectedUsageRecord}"



As you can see, SelectedItem is bound to SelectedUsageRecord property. But I need to be able to handle selecting multiple records. Is this possible to bind multiple records to a collection property? I don't see anything like "SelectedItems"...
Thanks.










share|improve this question


















  • 1





    What DataGrid are you using? I know that with the telerik DataGrid you can do ContainerBindings so IsSelected can be bound to a Customer in the Customers collection. From there it's easy to find the selected items.

    – Derek Beattie
    Jun 4 '12 at 22:17
















4















I have a WPF application using Caliburn.Micro.



The DataGrid has an attribute SelectedItem="{Binding Path=SelectedUsageRecord}"



As you can see, SelectedItem is bound to SelectedUsageRecord property. But I need to be able to handle selecting multiple records. Is this possible to bind multiple records to a collection property? I don't see anything like "SelectedItems"...
Thanks.










share|improve this question


















  • 1





    What DataGrid are you using? I know that with the telerik DataGrid you can do ContainerBindings so IsSelected can be bound to a Customer in the Customers collection. From there it's easy to find the selected items.

    – Derek Beattie
    Jun 4 '12 at 22:17














4












4








4


1






I have a WPF application using Caliburn.Micro.



The DataGrid has an attribute SelectedItem="{Binding Path=SelectedUsageRecord}"



As you can see, SelectedItem is bound to SelectedUsageRecord property. But I need to be able to handle selecting multiple records. Is this possible to bind multiple records to a collection property? I don't see anything like "SelectedItems"...
Thanks.










share|improve this question














I have a WPF application using Caliburn.Micro.



The DataGrid has an attribute SelectedItem="{Binding Path=SelectedUsageRecord}"



As you can see, SelectedItem is bound to SelectedUsageRecord property. But I need to be able to handle selecting multiple records. Is this possible to bind multiple records to a collection property? I don't see anything like "SelectedItems"...
Thanks.







wpf caliburn.micro






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked May 23 '12 at 14:14









David ShochetDavid Shochet

1,865102959




1,865102959








  • 1





    What DataGrid are you using? I know that with the telerik DataGrid you can do ContainerBindings so IsSelected can be bound to a Customer in the Customers collection. From there it's easy to find the selected items.

    – Derek Beattie
    Jun 4 '12 at 22:17














  • 1





    What DataGrid are you using? I know that with the telerik DataGrid you can do ContainerBindings so IsSelected can be bound to a Customer in the Customers collection. From there it's easy to find the selected items.

    – Derek Beattie
    Jun 4 '12 at 22:17








1




1





What DataGrid are you using? I know that with the telerik DataGrid you can do ContainerBindings so IsSelected can be bound to a Customer in the Customers collection. From there it's easy to find the selected items.

– Derek Beattie
Jun 4 '12 at 22:17





What DataGrid are you using? I know that with the telerik DataGrid you can do ContainerBindings so IsSelected can be bound to a Customer in the Customers collection. From there it's easy to find the selected items.

– Derek Beattie
Jun 4 '12 at 22:17












3 Answers
3






active

oldest

votes


















6














Here's what I did after striking the same scenario as you. In short handle the selection change event directly and pull the selected rows from the event args.
Assuming a source collection of "Rows" each one being a RowViewModel, and a collection for the "_selectedRows".



<DataGrid RowsSource="{Binding Rows}" x:Name="Rows"                  
SelectionMode="Extended" SelectionUnit="FullRow">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<cal:ActionMessage MethodName="SelectedRowsChangeEvent">
<cal:Parameter Value="$eventArgs" />
</cal:ActionMessage>
</i:EventTrigger>
</i:Interaction.Triggers>
</DataGrid>


public void SelectedRowsChangeEvent(SelectionChangedEventArgs e)
{
foreach (var addedRow in e.AddedRows)
{
_selectedRows.Add(addedRow as RowViewModel);
}

foreach (var removedRow in e.RemovedRows)
{
_selectedRows.Remove(removedRow as RowViewModel);
}
}





share|improve this answer































    4














    I just wanted to post my solution. In Caliburn micro there is no need to set the source as long as you stay true to the naming convention.



    Xaml



    <DataGrid x:Name="Rows" SelectionMode="Extended" cal:Message.Attach="[Event SelectionChanged] = [Row_SelectionChanged($eventArgs)]">


    C#



    public List<MyObject> Rows { get; set; }

    public MyObject SelectedRow { get; set; } //Will be set by Caliburn Micro. No need to use "SelectedItem={...}"

    List<MyObject> _selectedObjects = new List<MyObject>();

    public void Row_SelectionChanged(SelectionChangedEventArgs obj)
    {
    _selectedObjects.AddRange(obj.AddedItems.Cast<MyObject>());
    obj.RemovedItems.Cast<MyObject>().ToList().ForEach(w => _selectedObjects.Remove(w));
    }





    share|improve this answer































      2














      Both solutions posted here work fine but they rely on adding a view (wpf) assembly in your viewmodel because of the "SelectionChangedEventArgs" property. This, i think, is not good for cross platform solutions in case you intend to reuse the viewmodels in different platforms.



      So, i'm posting my solution that it's more in line with the MVVM pattern. I'm using syncfusion SfDataGrid in this example but this should work fine with a normal DataGrid:



      First we need to extend the DataGrid class, so we create a class. I named it "CustomSfDataGrid.cs". Note that i'm also subscribing to the SelectionChanged event and just obtaining the data directly from the "SelectedItems" property.



      using System.Windows;
      using Caliburn.Micro;
      using Syncfusion.UI.Xaml.Grid;

      namespace DesktopClient.WPF.Controls
      {
      public class CustomSfDataGrid : SfDataGrid
      {
      ///Bindable collection of objects property linked to the DependencyProperty called: "CustomSelectedItems"
      ///We can use "CustomSelectedItems" as a Binding Property in WPF
      public BindableCollection<object> CustomSelectedItems
      {
      get
      {
      return (BindableCollection<object>)GetValue(CustomSelectedItemsProperty);
      }
      set
      {
      SetValue(CustomSelectedItemsProperty, value);
      }
      }

      // Using a DependencyProperty as the backing store for SelectedItem. This enables animation, styling, binding, etc...
      public static readonly DependencyProperty CustomSelectedItemsProperty = DependencyProperty.Register("CustomSelectedItems", typeof(BindableCollection<object>), typeof(CustomSfDataGrid), new PropertyMetadata(null));

      public CustomSfDataGrid()
      {
      SelectionChanged += CustomSfDataGrid_SelectionChanged;
      }

      private void CustomSfDataGrid_SelectionChanged(object sender, GridSelectionChangedEventArgs e)
      {
      this.CustomSelectedItems = new BindableCollection<object>(this.SelectedItems);
      }
      }
      }


      In the .xaml file i added a header called "custom" that is pointing to the namespace of my "CustomSfDataGrid.cs". Then, i'm binding the new "CustomSelectedItems" property to "MyViewModelProperty". Finally, i'm using the "SelectionChanged" event.



      <UserControl
      xmlns:syncfusion="http://schemas.syncfusion.com/wpf"
      xmlns:cal="http://www.caliburnproject.org"
      xmlns:custom="clr-namespace:DesktopClient.WPF.Controls">
      <Grid>
      <custom:CustomSfDataGrid x:Name="dataGrid" ItemsSource="{Binding Models}"
      SelectionMode="Extended" SelectionChanged="OnSelectionChanged"
      CustomSelectedItems="{Binding MyViewModelProperty, Mode=OneWayToSource}">
      <syncfusion:SfDataGrid.Columns>
      <!-- Column Schema -->
      </syncfusion:SfDataGrid.Columns>
      </custom:CustomSfDataGrid>
      </Grid>


      Finally, in the ViewModel i have a "BindableCollection" property.



      using using System.Linq;
      //
      //...
      private BindableCollection<object> _myViewModelProperty;

      public BindableCollection<object> MyViewModelProperty
      {
      get
      {
      return _myViewModelProperty;
      }
      set
      {
      _myViewModelProperty = value;
      }
      }

      //
      public void UsingMyViewModel()
      {
      //cast the collection of objects to a different type using linq
      BindableCollection<MyCastedType> x = new BindableCollection<BrandModel>(MyViewModelProperty.OfType<BrandModel>());

      //alternative casting method
      BindableCollection<MyCastedType> y = new BindableCollection<MyCastedType>();
      foreach (var item in MyViewModelProperty)
      {
      y.Add(item as MyCastedType);
      }
      }





      share|improve this answer


























      • Ok... so apparently just binding the "SelectedItems" xaml property to a ObservableCollection<objects> property in the viewmodel works fine. No need to extend the class. I'm keeping my original post just in case someone still finds it useful.

        – Dev Kevin
        Nov 20 '18 at 5:08













      • Hi Im currently using your approach in my app and it works perfect with an standard datagrid, the only problem is when I try to update the selected items from viewmodel it dont works. Is there any solution for this. Note: binding directly SelectedItems to an ObservableCollection dont work in an standard datagrid.

        – Alexei Agüero Alba
        Jan 25 at 12:55











      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f10721794%2fselecting-multiple-records-in-datagrid-with-caliburn-micro%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      3 Answers
      3






      active

      oldest

      votes








      3 Answers
      3






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      6














      Here's what I did after striking the same scenario as you. In short handle the selection change event directly and pull the selected rows from the event args.
      Assuming a source collection of "Rows" each one being a RowViewModel, and a collection for the "_selectedRows".



      <DataGrid RowsSource="{Binding Rows}" x:Name="Rows"                  
      SelectionMode="Extended" SelectionUnit="FullRow">
      <i:Interaction.Triggers>
      <i:EventTrigger EventName="SelectionChanged">
      <cal:ActionMessage MethodName="SelectedRowsChangeEvent">
      <cal:Parameter Value="$eventArgs" />
      </cal:ActionMessage>
      </i:EventTrigger>
      </i:Interaction.Triggers>
      </DataGrid>


      public void SelectedRowsChangeEvent(SelectionChangedEventArgs e)
      {
      foreach (var addedRow in e.AddedRows)
      {
      _selectedRows.Add(addedRow as RowViewModel);
      }

      foreach (var removedRow in e.RemovedRows)
      {
      _selectedRows.Remove(removedRow as RowViewModel);
      }
      }





      share|improve this answer




























        6














        Here's what I did after striking the same scenario as you. In short handle the selection change event directly and pull the selected rows from the event args.
        Assuming a source collection of "Rows" each one being a RowViewModel, and a collection for the "_selectedRows".



        <DataGrid RowsSource="{Binding Rows}" x:Name="Rows"                  
        SelectionMode="Extended" SelectionUnit="FullRow">
        <i:Interaction.Triggers>
        <i:EventTrigger EventName="SelectionChanged">
        <cal:ActionMessage MethodName="SelectedRowsChangeEvent">
        <cal:Parameter Value="$eventArgs" />
        </cal:ActionMessage>
        </i:EventTrigger>
        </i:Interaction.Triggers>
        </DataGrid>


        public void SelectedRowsChangeEvent(SelectionChangedEventArgs e)
        {
        foreach (var addedRow in e.AddedRows)
        {
        _selectedRows.Add(addedRow as RowViewModel);
        }

        foreach (var removedRow in e.RemovedRows)
        {
        _selectedRows.Remove(removedRow as RowViewModel);
        }
        }





        share|improve this answer


























          6












          6








          6







          Here's what I did after striking the same scenario as you. In short handle the selection change event directly and pull the selected rows from the event args.
          Assuming a source collection of "Rows" each one being a RowViewModel, and a collection for the "_selectedRows".



          <DataGrid RowsSource="{Binding Rows}" x:Name="Rows"                  
          SelectionMode="Extended" SelectionUnit="FullRow">
          <i:Interaction.Triggers>
          <i:EventTrigger EventName="SelectionChanged">
          <cal:ActionMessage MethodName="SelectedRowsChangeEvent">
          <cal:Parameter Value="$eventArgs" />
          </cal:ActionMessage>
          </i:EventTrigger>
          </i:Interaction.Triggers>
          </DataGrid>


          public void SelectedRowsChangeEvent(SelectionChangedEventArgs e)
          {
          foreach (var addedRow in e.AddedRows)
          {
          _selectedRows.Add(addedRow as RowViewModel);
          }

          foreach (var removedRow in e.RemovedRows)
          {
          _selectedRows.Remove(removedRow as RowViewModel);
          }
          }





          share|improve this answer













          Here's what I did after striking the same scenario as you. In short handle the selection change event directly and pull the selected rows from the event args.
          Assuming a source collection of "Rows" each one being a RowViewModel, and a collection for the "_selectedRows".



          <DataGrid RowsSource="{Binding Rows}" x:Name="Rows"                  
          SelectionMode="Extended" SelectionUnit="FullRow">
          <i:Interaction.Triggers>
          <i:EventTrigger EventName="SelectionChanged">
          <cal:ActionMessage MethodName="SelectedRowsChangeEvent">
          <cal:Parameter Value="$eventArgs" />
          </cal:ActionMessage>
          </i:EventTrigger>
          </i:Interaction.Triggers>
          </DataGrid>


          public void SelectedRowsChangeEvent(SelectionChangedEventArgs e)
          {
          foreach (var addedRow in e.AddedRows)
          {
          _selectedRows.Add(addedRow as RowViewModel);
          }

          foreach (var removedRow in e.RemovedRows)
          {
          _selectedRows.Remove(removedRow as RowViewModel);
          }
          }






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 1 '12 at 2:04









          DaveDave

          7612




          7612

























              4














              I just wanted to post my solution. In Caliburn micro there is no need to set the source as long as you stay true to the naming convention.



              Xaml



              <DataGrid x:Name="Rows" SelectionMode="Extended" cal:Message.Attach="[Event SelectionChanged] = [Row_SelectionChanged($eventArgs)]">


              C#



              public List<MyObject> Rows { get; set; }

              public MyObject SelectedRow { get; set; } //Will be set by Caliburn Micro. No need to use "SelectedItem={...}"

              List<MyObject> _selectedObjects = new List<MyObject>();

              public void Row_SelectionChanged(SelectionChangedEventArgs obj)
              {
              _selectedObjects.AddRange(obj.AddedItems.Cast<MyObject>());
              obj.RemovedItems.Cast<MyObject>().ToList().ForEach(w => _selectedObjects.Remove(w));
              }





              share|improve this answer




























                4














                I just wanted to post my solution. In Caliburn micro there is no need to set the source as long as you stay true to the naming convention.



                Xaml



                <DataGrid x:Name="Rows" SelectionMode="Extended" cal:Message.Attach="[Event SelectionChanged] = [Row_SelectionChanged($eventArgs)]">


                C#



                public List<MyObject> Rows { get; set; }

                public MyObject SelectedRow { get; set; } //Will be set by Caliburn Micro. No need to use "SelectedItem={...}"

                List<MyObject> _selectedObjects = new List<MyObject>();

                public void Row_SelectionChanged(SelectionChangedEventArgs obj)
                {
                _selectedObjects.AddRange(obj.AddedItems.Cast<MyObject>());
                obj.RemovedItems.Cast<MyObject>().ToList().ForEach(w => _selectedObjects.Remove(w));
                }





                share|improve this answer


























                  4












                  4








                  4







                  I just wanted to post my solution. In Caliburn micro there is no need to set the source as long as you stay true to the naming convention.



                  Xaml



                  <DataGrid x:Name="Rows" SelectionMode="Extended" cal:Message.Attach="[Event SelectionChanged] = [Row_SelectionChanged($eventArgs)]">


                  C#



                  public List<MyObject> Rows { get; set; }

                  public MyObject SelectedRow { get; set; } //Will be set by Caliburn Micro. No need to use "SelectedItem={...}"

                  List<MyObject> _selectedObjects = new List<MyObject>();

                  public void Row_SelectionChanged(SelectionChangedEventArgs obj)
                  {
                  _selectedObjects.AddRange(obj.AddedItems.Cast<MyObject>());
                  obj.RemovedItems.Cast<MyObject>().ToList().ForEach(w => _selectedObjects.Remove(w));
                  }





                  share|improve this answer













                  I just wanted to post my solution. In Caliburn micro there is no need to set the source as long as you stay true to the naming convention.



                  Xaml



                  <DataGrid x:Name="Rows" SelectionMode="Extended" cal:Message.Attach="[Event SelectionChanged] = [Row_SelectionChanged($eventArgs)]">


                  C#



                  public List<MyObject> Rows { get; set; }

                  public MyObject SelectedRow { get; set; } //Will be set by Caliburn Micro. No need to use "SelectedItem={...}"

                  List<MyObject> _selectedObjects = new List<MyObject>();

                  public void Row_SelectionChanged(SelectionChangedEventArgs obj)
                  {
                  _selectedObjects.AddRange(obj.AddedItems.Cast<MyObject>());
                  obj.RemovedItems.Cast<MyObject>().ToList().ForEach(w => _selectedObjects.Remove(w));
                  }






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Jan 10 '17 at 7:24









                  RahbekRahbek

                  70185




                  70185























                      2














                      Both solutions posted here work fine but they rely on adding a view (wpf) assembly in your viewmodel because of the "SelectionChangedEventArgs" property. This, i think, is not good for cross platform solutions in case you intend to reuse the viewmodels in different platforms.



                      So, i'm posting my solution that it's more in line with the MVVM pattern. I'm using syncfusion SfDataGrid in this example but this should work fine with a normal DataGrid:



                      First we need to extend the DataGrid class, so we create a class. I named it "CustomSfDataGrid.cs". Note that i'm also subscribing to the SelectionChanged event and just obtaining the data directly from the "SelectedItems" property.



                      using System.Windows;
                      using Caliburn.Micro;
                      using Syncfusion.UI.Xaml.Grid;

                      namespace DesktopClient.WPF.Controls
                      {
                      public class CustomSfDataGrid : SfDataGrid
                      {
                      ///Bindable collection of objects property linked to the DependencyProperty called: "CustomSelectedItems"
                      ///We can use "CustomSelectedItems" as a Binding Property in WPF
                      public BindableCollection<object> CustomSelectedItems
                      {
                      get
                      {
                      return (BindableCollection<object>)GetValue(CustomSelectedItemsProperty);
                      }
                      set
                      {
                      SetValue(CustomSelectedItemsProperty, value);
                      }
                      }

                      // Using a DependencyProperty as the backing store for SelectedItem. This enables animation, styling, binding, etc...
                      public static readonly DependencyProperty CustomSelectedItemsProperty = DependencyProperty.Register("CustomSelectedItems", typeof(BindableCollection<object>), typeof(CustomSfDataGrid), new PropertyMetadata(null));

                      public CustomSfDataGrid()
                      {
                      SelectionChanged += CustomSfDataGrid_SelectionChanged;
                      }

                      private void CustomSfDataGrid_SelectionChanged(object sender, GridSelectionChangedEventArgs e)
                      {
                      this.CustomSelectedItems = new BindableCollection<object>(this.SelectedItems);
                      }
                      }
                      }


                      In the .xaml file i added a header called "custom" that is pointing to the namespace of my "CustomSfDataGrid.cs". Then, i'm binding the new "CustomSelectedItems" property to "MyViewModelProperty". Finally, i'm using the "SelectionChanged" event.



                      <UserControl
                      xmlns:syncfusion="http://schemas.syncfusion.com/wpf"
                      xmlns:cal="http://www.caliburnproject.org"
                      xmlns:custom="clr-namespace:DesktopClient.WPF.Controls">
                      <Grid>
                      <custom:CustomSfDataGrid x:Name="dataGrid" ItemsSource="{Binding Models}"
                      SelectionMode="Extended" SelectionChanged="OnSelectionChanged"
                      CustomSelectedItems="{Binding MyViewModelProperty, Mode=OneWayToSource}">
                      <syncfusion:SfDataGrid.Columns>
                      <!-- Column Schema -->
                      </syncfusion:SfDataGrid.Columns>
                      </custom:CustomSfDataGrid>
                      </Grid>


                      Finally, in the ViewModel i have a "BindableCollection" property.



                      using using System.Linq;
                      //
                      //...
                      private BindableCollection<object> _myViewModelProperty;

                      public BindableCollection<object> MyViewModelProperty
                      {
                      get
                      {
                      return _myViewModelProperty;
                      }
                      set
                      {
                      _myViewModelProperty = value;
                      }
                      }

                      //
                      public void UsingMyViewModel()
                      {
                      //cast the collection of objects to a different type using linq
                      BindableCollection<MyCastedType> x = new BindableCollection<BrandModel>(MyViewModelProperty.OfType<BrandModel>());

                      //alternative casting method
                      BindableCollection<MyCastedType> y = new BindableCollection<MyCastedType>();
                      foreach (var item in MyViewModelProperty)
                      {
                      y.Add(item as MyCastedType);
                      }
                      }





                      share|improve this answer


























                      • Ok... so apparently just binding the "SelectedItems" xaml property to a ObservableCollection<objects> property in the viewmodel works fine. No need to extend the class. I'm keeping my original post just in case someone still finds it useful.

                        – Dev Kevin
                        Nov 20 '18 at 5:08













                      • Hi Im currently using your approach in my app and it works perfect with an standard datagrid, the only problem is when I try to update the selected items from viewmodel it dont works. Is there any solution for this. Note: binding directly SelectedItems to an ObservableCollection dont work in an standard datagrid.

                        – Alexei Agüero Alba
                        Jan 25 at 12:55
















                      2














                      Both solutions posted here work fine but they rely on adding a view (wpf) assembly in your viewmodel because of the "SelectionChangedEventArgs" property. This, i think, is not good for cross platform solutions in case you intend to reuse the viewmodels in different platforms.



                      So, i'm posting my solution that it's more in line with the MVVM pattern. I'm using syncfusion SfDataGrid in this example but this should work fine with a normal DataGrid:



                      First we need to extend the DataGrid class, so we create a class. I named it "CustomSfDataGrid.cs". Note that i'm also subscribing to the SelectionChanged event and just obtaining the data directly from the "SelectedItems" property.



                      using System.Windows;
                      using Caliburn.Micro;
                      using Syncfusion.UI.Xaml.Grid;

                      namespace DesktopClient.WPF.Controls
                      {
                      public class CustomSfDataGrid : SfDataGrid
                      {
                      ///Bindable collection of objects property linked to the DependencyProperty called: "CustomSelectedItems"
                      ///We can use "CustomSelectedItems" as a Binding Property in WPF
                      public BindableCollection<object> CustomSelectedItems
                      {
                      get
                      {
                      return (BindableCollection<object>)GetValue(CustomSelectedItemsProperty);
                      }
                      set
                      {
                      SetValue(CustomSelectedItemsProperty, value);
                      }
                      }

                      // Using a DependencyProperty as the backing store for SelectedItem. This enables animation, styling, binding, etc...
                      public static readonly DependencyProperty CustomSelectedItemsProperty = DependencyProperty.Register("CustomSelectedItems", typeof(BindableCollection<object>), typeof(CustomSfDataGrid), new PropertyMetadata(null));

                      public CustomSfDataGrid()
                      {
                      SelectionChanged += CustomSfDataGrid_SelectionChanged;
                      }

                      private void CustomSfDataGrid_SelectionChanged(object sender, GridSelectionChangedEventArgs e)
                      {
                      this.CustomSelectedItems = new BindableCollection<object>(this.SelectedItems);
                      }
                      }
                      }


                      In the .xaml file i added a header called "custom" that is pointing to the namespace of my "CustomSfDataGrid.cs". Then, i'm binding the new "CustomSelectedItems" property to "MyViewModelProperty". Finally, i'm using the "SelectionChanged" event.



                      <UserControl
                      xmlns:syncfusion="http://schemas.syncfusion.com/wpf"
                      xmlns:cal="http://www.caliburnproject.org"
                      xmlns:custom="clr-namespace:DesktopClient.WPF.Controls">
                      <Grid>
                      <custom:CustomSfDataGrid x:Name="dataGrid" ItemsSource="{Binding Models}"
                      SelectionMode="Extended" SelectionChanged="OnSelectionChanged"
                      CustomSelectedItems="{Binding MyViewModelProperty, Mode=OneWayToSource}">
                      <syncfusion:SfDataGrid.Columns>
                      <!-- Column Schema -->
                      </syncfusion:SfDataGrid.Columns>
                      </custom:CustomSfDataGrid>
                      </Grid>


                      Finally, in the ViewModel i have a "BindableCollection" property.



                      using using System.Linq;
                      //
                      //...
                      private BindableCollection<object> _myViewModelProperty;

                      public BindableCollection<object> MyViewModelProperty
                      {
                      get
                      {
                      return _myViewModelProperty;
                      }
                      set
                      {
                      _myViewModelProperty = value;
                      }
                      }

                      //
                      public void UsingMyViewModel()
                      {
                      //cast the collection of objects to a different type using linq
                      BindableCollection<MyCastedType> x = new BindableCollection<BrandModel>(MyViewModelProperty.OfType<BrandModel>());

                      //alternative casting method
                      BindableCollection<MyCastedType> y = new BindableCollection<MyCastedType>();
                      foreach (var item in MyViewModelProperty)
                      {
                      y.Add(item as MyCastedType);
                      }
                      }





                      share|improve this answer


























                      • Ok... so apparently just binding the "SelectedItems" xaml property to a ObservableCollection<objects> property in the viewmodel works fine. No need to extend the class. I'm keeping my original post just in case someone still finds it useful.

                        – Dev Kevin
                        Nov 20 '18 at 5:08













                      • Hi Im currently using your approach in my app and it works perfect with an standard datagrid, the only problem is when I try to update the selected items from viewmodel it dont works. Is there any solution for this. Note: binding directly SelectedItems to an ObservableCollection dont work in an standard datagrid.

                        – Alexei Agüero Alba
                        Jan 25 at 12:55














                      2












                      2








                      2







                      Both solutions posted here work fine but they rely on adding a view (wpf) assembly in your viewmodel because of the "SelectionChangedEventArgs" property. This, i think, is not good for cross platform solutions in case you intend to reuse the viewmodels in different platforms.



                      So, i'm posting my solution that it's more in line with the MVVM pattern. I'm using syncfusion SfDataGrid in this example but this should work fine with a normal DataGrid:



                      First we need to extend the DataGrid class, so we create a class. I named it "CustomSfDataGrid.cs". Note that i'm also subscribing to the SelectionChanged event and just obtaining the data directly from the "SelectedItems" property.



                      using System.Windows;
                      using Caliburn.Micro;
                      using Syncfusion.UI.Xaml.Grid;

                      namespace DesktopClient.WPF.Controls
                      {
                      public class CustomSfDataGrid : SfDataGrid
                      {
                      ///Bindable collection of objects property linked to the DependencyProperty called: "CustomSelectedItems"
                      ///We can use "CustomSelectedItems" as a Binding Property in WPF
                      public BindableCollection<object> CustomSelectedItems
                      {
                      get
                      {
                      return (BindableCollection<object>)GetValue(CustomSelectedItemsProperty);
                      }
                      set
                      {
                      SetValue(CustomSelectedItemsProperty, value);
                      }
                      }

                      // Using a DependencyProperty as the backing store for SelectedItem. This enables animation, styling, binding, etc...
                      public static readonly DependencyProperty CustomSelectedItemsProperty = DependencyProperty.Register("CustomSelectedItems", typeof(BindableCollection<object>), typeof(CustomSfDataGrid), new PropertyMetadata(null));

                      public CustomSfDataGrid()
                      {
                      SelectionChanged += CustomSfDataGrid_SelectionChanged;
                      }

                      private void CustomSfDataGrid_SelectionChanged(object sender, GridSelectionChangedEventArgs e)
                      {
                      this.CustomSelectedItems = new BindableCollection<object>(this.SelectedItems);
                      }
                      }
                      }


                      In the .xaml file i added a header called "custom" that is pointing to the namespace of my "CustomSfDataGrid.cs". Then, i'm binding the new "CustomSelectedItems" property to "MyViewModelProperty". Finally, i'm using the "SelectionChanged" event.



                      <UserControl
                      xmlns:syncfusion="http://schemas.syncfusion.com/wpf"
                      xmlns:cal="http://www.caliburnproject.org"
                      xmlns:custom="clr-namespace:DesktopClient.WPF.Controls">
                      <Grid>
                      <custom:CustomSfDataGrid x:Name="dataGrid" ItemsSource="{Binding Models}"
                      SelectionMode="Extended" SelectionChanged="OnSelectionChanged"
                      CustomSelectedItems="{Binding MyViewModelProperty, Mode=OneWayToSource}">
                      <syncfusion:SfDataGrid.Columns>
                      <!-- Column Schema -->
                      </syncfusion:SfDataGrid.Columns>
                      </custom:CustomSfDataGrid>
                      </Grid>


                      Finally, in the ViewModel i have a "BindableCollection" property.



                      using using System.Linq;
                      //
                      //...
                      private BindableCollection<object> _myViewModelProperty;

                      public BindableCollection<object> MyViewModelProperty
                      {
                      get
                      {
                      return _myViewModelProperty;
                      }
                      set
                      {
                      _myViewModelProperty = value;
                      }
                      }

                      //
                      public void UsingMyViewModel()
                      {
                      //cast the collection of objects to a different type using linq
                      BindableCollection<MyCastedType> x = new BindableCollection<BrandModel>(MyViewModelProperty.OfType<BrandModel>());

                      //alternative casting method
                      BindableCollection<MyCastedType> y = new BindableCollection<MyCastedType>();
                      foreach (var item in MyViewModelProperty)
                      {
                      y.Add(item as MyCastedType);
                      }
                      }





                      share|improve this answer















                      Both solutions posted here work fine but they rely on adding a view (wpf) assembly in your viewmodel because of the "SelectionChangedEventArgs" property. This, i think, is not good for cross platform solutions in case you intend to reuse the viewmodels in different platforms.



                      So, i'm posting my solution that it's more in line with the MVVM pattern. I'm using syncfusion SfDataGrid in this example but this should work fine with a normal DataGrid:



                      First we need to extend the DataGrid class, so we create a class. I named it "CustomSfDataGrid.cs". Note that i'm also subscribing to the SelectionChanged event and just obtaining the data directly from the "SelectedItems" property.



                      using System.Windows;
                      using Caliburn.Micro;
                      using Syncfusion.UI.Xaml.Grid;

                      namespace DesktopClient.WPF.Controls
                      {
                      public class CustomSfDataGrid : SfDataGrid
                      {
                      ///Bindable collection of objects property linked to the DependencyProperty called: "CustomSelectedItems"
                      ///We can use "CustomSelectedItems" as a Binding Property in WPF
                      public BindableCollection<object> CustomSelectedItems
                      {
                      get
                      {
                      return (BindableCollection<object>)GetValue(CustomSelectedItemsProperty);
                      }
                      set
                      {
                      SetValue(CustomSelectedItemsProperty, value);
                      }
                      }

                      // Using a DependencyProperty as the backing store for SelectedItem. This enables animation, styling, binding, etc...
                      public static readonly DependencyProperty CustomSelectedItemsProperty = DependencyProperty.Register("CustomSelectedItems", typeof(BindableCollection<object>), typeof(CustomSfDataGrid), new PropertyMetadata(null));

                      public CustomSfDataGrid()
                      {
                      SelectionChanged += CustomSfDataGrid_SelectionChanged;
                      }

                      private void CustomSfDataGrid_SelectionChanged(object sender, GridSelectionChangedEventArgs e)
                      {
                      this.CustomSelectedItems = new BindableCollection<object>(this.SelectedItems);
                      }
                      }
                      }


                      In the .xaml file i added a header called "custom" that is pointing to the namespace of my "CustomSfDataGrid.cs". Then, i'm binding the new "CustomSelectedItems" property to "MyViewModelProperty". Finally, i'm using the "SelectionChanged" event.



                      <UserControl
                      xmlns:syncfusion="http://schemas.syncfusion.com/wpf"
                      xmlns:cal="http://www.caliburnproject.org"
                      xmlns:custom="clr-namespace:DesktopClient.WPF.Controls">
                      <Grid>
                      <custom:CustomSfDataGrid x:Name="dataGrid" ItemsSource="{Binding Models}"
                      SelectionMode="Extended" SelectionChanged="OnSelectionChanged"
                      CustomSelectedItems="{Binding MyViewModelProperty, Mode=OneWayToSource}">
                      <syncfusion:SfDataGrid.Columns>
                      <!-- Column Schema -->
                      </syncfusion:SfDataGrid.Columns>
                      </custom:CustomSfDataGrid>
                      </Grid>


                      Finally, in the ViewModel i have a "BindableCollection" property.



                      using using System.Linq;
                      //
                      //...
                      private BindableCollection<object> _myViewModelProperty;

                      public BindableCollection<object> MyViewModelProperty
                      {
                      get
                      {
                      return _myViewModelProperty;
                      }
                      set
                      {
                      _myViewModelProperty = value;
                      }
                      }

                      //
                      public void UsingMyViewModel()
                      {
                      //cast the collection of objects to a different type using linq
                      BindableCollection<MyCastedType> x = new BindableCollection<BrandModel>(MyViewModelProperty.OfType<BrandModel>());

                      //alternative casting method
                      BindableCollection<MyCastedType> y = new BindableCollection<MyCastedType>();
                      foreach (var item in MyViewModelProperty)
                      {
                      y.Add(item as MyCastedType);
                      }
                      }






                      share|improve this answer














                      share|improve this answer



                      share|improve this answer








                      edited Nov 20 '18 at 4:59

























                      answered Nov 20 '18 at 4:30









                      Dev KevinDev Kevin

                      412




                      412













                      • Ok... so apparently just binding the "SelectedItems" xaml property to a ObservableCollection<objects> property in the viewmodel works fine. No need to extend the class. I'm keeping my original post just in case someone still finds it useful.

                        – Dev Kevin
                        Nov 20 '18 at 5:08













                      • Hi Im currently using your approach in my app and it works perfect with an standard datagrid, the only problem is when I try to update the selected items from viewmodel it dont works. Is there any solution for this. Note: binding directly SelectedItems to an ObservableCollection dont work in an standard datagrid.

                        – Alexei Agüero Alba
                        Jan 25 at 12:55



















                      • Ok... so apparently just binding the "SelectedItems" xaml property to a ObservableCollection<objects> property in the viewmodel works fine. No need to extend the class. I'm keeping my original post just in case someone still finds it useful.

                        – Dev Kevin
                        Nov 20 '18 at 5:08













                      • Hi Im currently using your approach in my app and it works perfect with an standard datagrid, the only problem is when I try to update the selected items from viewmodel it dont works. Is there any solution for this. Note: binding directly SelectedItems to an ObservableCollection dont work in an standard datagrid.

                        – Alexei Agüero Alba
                        Jan 25 at 12:55

















                      Ok... so apparently just binding the "SelectedItems" xaml property to a ObservableCollection<objects> property in the viewmodel works fine. No need to extend the class. I'm keeping my original post just in case someone still finds it useful.

                      – Dev Kevin
                      Nov 20 '18 at 5:08







                      Ok... so apparently just binding the "SelectedItems" xaml property to a ObservableCollection<objects> property in the viewmodel works fine. No need to extend the class. I'm keeping my original post just in case someone still finds it useful.

                      – Dev Kevin
                      Nov 20 '18 at 5:08















                      Hi Im currently using your approach in my app and it works perfect with an standard datagrid, the only problem is when I try to update the selected items from viewmodel it dont works. Is there any solution for this. Note: binding directly SelectedItems to an ObservableCollection dont work in an standard datagrid.

                      – Alexei Agüero Alba
                      Jan 25 at 12:55





                      Hi Im currently using your approach in my app and it works perfect with an standard datagrid, the only problem is when I try to update the selected items from viewmodel it dont works. Is there any solution for this. Note: binding directly SelectedItems to an ObservableCollection dont work in an standard datagrid.

                      – Alexei Agüero Alba
                      Jan 25 at 12:55


















                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f10721794%2fselecting-multiple-records-in-datagrid-with-caliburn-micro%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      這個網誌中的熱門文章

                      Tangent Lines Diagram Along Smooth Curve

                      Yusuf al-Mu'taman ibn Hud

                      Zucchini