none
How to filter child DataGrid based on parent DataGrid current row

    Question

  • UserControl contains parent and child datagrids.
    Child datagrid should display only items corresponding to parent DataGrid curret item.

    Child DataGrid ItemsSource is set at Loaded event handler:

    PagedCollectionView _pcv;
    IList Modifieds = ....
    ...
    _pcv = new PagedCollectionView(Modifieds);
    _pcv.Filter = new Predicate<object>(FilterCompletedTasks);
    _pcv.PageSize = int.MaxValue;
    ChildDataGrid.ItemsSource = _pcv;

    bool FilterCompletedTasks(object t)
    {
    EntityBase task = (EntityBase)t;
    return task.GetValue("Isik").ToString() == ParentDataGrid.CurrentEntity.GetValue("Isik").ToString();
    }

    ParentDataGrid SelectionChanged event handler contains code to refresh filter:

    ParentDataGrid.Dispatcher.BeginInvoke(() => { _pcv.Refresh(); });

    If master DataGrid current row changes, exception occurs in _pcv.Refresh() always:

    "'Refresh' is not allowed during an AddNew or EditItem transaction."

    How to show filtered rows in child DataGrid when parent DataGrid selected row changes ?

    Andrus.

    Sunday, December 13, 2009 7:51 PM

All replies

  • I would try another way of refreshing the data,such as doing a clear and adding the PagedCollectionView again.

    Monday, December 14, 2009 6:06 AM
  • I changed refresh method to

    void ParentGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
       if (_pcv != null)
       {
        _pcv = new PagedCollectionView(My_IList);
        _pcv.Filter = new Predicate<object>(FilterCompletedTasks);
        _pcv.PageSize = int.MaxValue;
        ChildDataGrid.ItemsSource = _pcv;
    }
    }

    NullReferenceException below occurs at line

    ChildDataGrid.ItemsSource = _pcv;

    if this code is executed. 

    How to fix ?

    Andrus

     System.NullReferenceException was unhandled by user code
    Message="Object reference not set to an instance of an object."
    StackTrace:
         at System.Windows.Controls.DataGrid.EndCellEdit(DataGridEditAction editAction, Boolean exitEditingMode, Boolean keepFocus, Boolean raiseEvents)
         at System.Windows.Controls.DataGrid.CancelEdit(DataGridEditingUnit editingUnit, Boolean raiseEvents)
         at System.Windows.Controls.DataGrid.SetCurrentCellCore(Int32 columnIndex, Int32 slot, Boolean commitEdit, Boolean endRowEdit)
         at System.Windows.Controls.DataGrid.ClearRows(Boolean recycle)
         at System.Windows.Controls.DataGrid.OnItemsSourcePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
         at System.Windows.DependencyObject.RaisePropertyChangeNotifications(DependencyProperty dp, Object newValue, Object oldValue)
         at System.Windows.DependencyObject.SetValueInternal(DependencyProperty dp, Object value, Boolean allowReadOnlySet, Boolean isSetByStyle, Boolean isSetByBuiltInStyle, PropertyInvalidationReason reason)
         at System.Windows.DependencyObject.SetValueInternal(DependencyProperty dp, Object value)
         at System.Windows.DependencyObject.SetValue(DependencyProperty dp, Object value)
         at System.Windows.Controls.DataGrid.set_ItemsSource(IEnumerable value)
         at MyApp.Controls.ParentChildFormModel.BrowseGrid_SelectionChanged(Object sender, SelectionChangedEventArgs e)
         at System.Windows.Controls.DataGrid.OnSelectionChanged(SelectionChangedEventArgs e)
         at MyApp.Controls.DataGridBase.OnSelectionChanged(SelectionChangedEventArgs e)
         at System.Windows.Controls.DataGrid.FlushSelectionChanged()
         at System.Windows.Controls.DataGrid.set_NoSelectionChangeCount(Int32 value)
         at System.Windows.Controls.DataGrid.ProcessDownKeyInternal(Boolean shift, Boolean ctrl)
         at System.Windows.Controls.DataGrid.ProcessDownKey()
         at System.Windows.Controls.DataGrid.ProcessDataGridKey(KeyEventArgs e)
         at System.Windows.Controls.DataGrid.DataGrid_KeyDown(Object sender, KeyEventArgs e)
         at System.Windows.CoreInvokeHandler.InvokeEventHandler(Int32 typeIndex, Delegate handlerDelegate, Object sender, Object args)
         at MS.Internal.JoltHelper.FireEvent(IntPtr unmanagedObj, IntPtr unmanagedObjArgs, Int32 argsTypeIndex, String eventName)
     

    Monday, December 14, 2009 11:10 AM
  • I would try using a property rather than just a variable.  You could assign _pcv as:

    public PagedCollectionView pcv { get; set; };

    Monday, December 14, 2009 11:20 AM
  • I changed viewmodel to use Pcv property using code below.

    NullReferenceException still occurs now in Pcv property changed event handler. How to fix ?

    Andrus.

     

    using System;
    using System.Windows.Controls;
    using System.Windows.Data;
    using MyApp.Controls;
    
    public class ParentChildFormModelTest : DataModel, INotifyPropertyChanged
    {
        readonly VirtualDataGrid BrowseGrid;
        readonly DocumentRows RowDataGrid;
        readonly ParentChildForm VirtualGridForm;
    
        public PagedCollectionView Pcv
        {
            get
            {
                return _pcv;
            }
            set
            {
                if (_pcv == value)
                    return;
                _pcv = value;
                RaisePropertyChanged("Pcv");
            }
        }
        PagedCollectionView _pcv;
    
        public ParentChildFormModelTest(VirtualDataGrid browseGrid,
            DocumentRows rowDataGrid, ParentChildForm virtualGridForm)
        {
            BrowseGrid = browseGrid;
            RowDataGrid = rowDataGrid;
            VirtualGridForm = virtualGridForm;
        }
    
    
        void Form_Loaded()
        {
            var service = ServiceFactory.GetService();
            service.GetDataUsingDefaultSearchCompleted += (sender, e) =>
            {
                if (!ServiceFactory.AsyncCompleted(e, e.header))
                    return;
                RowDataGrid.DataSource.Definition = e.definition;
                RowDataGrid.Create();
                RowDataGrid.DataSource.Create(e.Result, RowDataGrid.DataSource.Definition, 0, false);
                Pcv = new PagedCollectionView(RowDataGrid.DataSource.Modifieds);
                Pcv.Filter = new Predicate<object>(FilterCompletedTasks);
                Pcv.PageSize = int.MaxValue;
            };
            service.GetDataUsingDefaultSearchAsync(Globals.Header, "Summav", true, 0, int.MaxValue, 0);
        }
    
        void BrowseGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (Pcv != null)
            {
                Pcv = new PagedCollectionView(RowDataGrid.DataSource.Modifieds);
                Pcv.Filter = new Predicate<object>(FilterCompletedTasks);
                Pcv.PageSize = int.MaxValue;
            }
        }
    
        bool FilterCompletedTasks(object t)
        {
            if (BrowseGrid.CurrentEntity == null)
                return false;
            EntityBase task = (EntityBase)t;
            bool res = task.GetValue("Isik").ToString() == BrowseGrid.CurrentEntity.GetValue("Isik").ToString();
            return res;
        }
    }

     XAML:

    <content:BaseForm x:Class="MyApp.Controls.ParentChildForm"
        xmlns:basics="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls" 
        xmlns="http://schemas.microsoft.com/client/2007" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    	xmlns:myGrid="clr-namespace:Eeva.Controls"
        xmlns:content="clr-namespace:Eeva.Controls" 
        xmlns:cmd="clr-namespace:SLCommandingDemo.Commanding"
        xmlns:eevacontrols="clr-namespace:MyApp.Controls" 
        >
    
        <Grid x:Name="LayoutRoot">
            <Grid.RowDefinitions>
                <RowDefinition  />
                <RowDefinition />
            </Grid.RowDefinitions>
    
                <myGrid:VirtualDataGrid x:Name="BrowseGrid" 
               />
    
            <eevacontrols:DocumentRows Grid.Row="1" 
     x:Name="rowDataGrid"
    ItemsSource="{Binding Pcv, Mode=TwoWay}"
              />
        </Grid>
    </content:BaseForm>

     

    Result:

    System.NullReferenceException was unhandled by user code
      Message="Object reference not set to an instance of an object."
      StackTrace:
           at System.Windows.Controls.DataGrid.EndCellEdit(DataGridEditAction editAction, Boolean exitEditingMode, Boolean keepFocus, Boolean raiseEvents)
           at System.Windows.Controls.DataGrid.CancelEdit(DataGridEditingUnit editingUnit, Boolean raiseEvents)
           at System.Windows.Controls.DataGrid.SetCurrentCellCore(Int32 columnIndex, Int32 slot, Boolean commitEdit, Boolean endRowEdit)
           at System.Windows.Controls.DataGrid.ClearRows(Boolean recycle)
           at System.Windows.Controls.DataGrid.OnItemsSourcePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
           at System.Windows.DependencyObject.RefreshBLOCKED EXPRESSION
           at System.Windows.Data.BindingExpression.RefreshBLOCKED EXPRESSION
           at System.Windows.Data.BindingExpression.SendDataToTarget()
           at System.Windows.Data.BindingExpression.SourcePropertyChanged(PropertyPathListener sender, PropertyPathChangedEventArgs args)
           at System.Windows.PropertyPathListener.RaisePropertyPathStepChanged(PropertyPathStep source)
           at System.Windows.PropertyAccessPathStep.RaisePropertyPathStepChanged(PropertyListener source)
           at System.Windows.CLRPropertyListener.SourcePropertyChanged(Object sender, PropertyChangedEventArgs args)
           at System.Windows.Data.WeakPropertyChangedListener.PropertyChangedCallback(Object sender, PropertyChangedEventArgs args)
           at System.ComponentModel.PropertyChangedEventHandler.Invoke(Object sender, PropertyChangedEventArgs e)
           at System.ComponentModel.Model.<>c__DisplayClass2.<RaisePropertyChanged>b__0(Object state)
      InnerException: 
    
     
    Monday, December 14, 2009 12:17 PM
  • In your Set method add:

    set

    {

        if (_pcv == value)

            return;

        if (value != null)

        {

            _pcv = value;

            RaisePropertyChanged("Pcv");

        }

    }

    Monday, December 14, 2009 12:25 PM
  • I added those lines. Same NRE still occurs. value in setter is never null since PagedCollectionView constructor returns non-null always.

    Andrus.

    System.NullReferenceException was unhandled by user code
      Message="Object reference not set to an instance of an object."
      StackTrace:
           at System.Windows.Controls.DataGrid.EndCellEdit(DataGridEditAction editAction, Boolean exitEditingMode, Boolean keepFocus, Boolean raiseEvents)
           at System.Windows.Controls.DataGrid.CancelEdit(DataGridEditingUnit editingUnit, Boolean raiseEvents)
           at System.Windows.Controls.DataGrid.SetCurrentCellCore(Int32 columnIndex, Int32 slot, Boolean commitEdit, Boolean endRowEdit)
           at System.Windows.Controls.DataGrid.ClearRows(Boolean recycle)
           at System.Windows.Controls.DataGrid.OnItemsSourcePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
           at System.Windows.DependencyObject.RefreshBLOCKED EXPRESSION
      InnerException:

    Monday, December 14, 2009 12:33 PM
  •  Have you tried adding this. before the RaisePropertyChanged event call?

    Monday, December 14, 2009 1:50 PM
  • No I havent tried to add this. I think adding this executes the same method so there is no difference.

    I have implemented EditOnEnter edit mode in DataGrid using base class

     

    partial class DataGridBase : DataGrid
        {
            protected override void OnCurrentCellChanged(EventArgs e)
            {
                base.OnCurrentCellChanged(e);
                BeginEdit();
            }
    
            protected override void OnSelectionChanged(SelectionChangedEventArgs e)
            {
                base.OnSelectionChanged(e);
                BeginEdit();
            }
    }
    
    

     If those BeginEdit() calls are removed, exception does not occur. It seems that PagedCollectionView class does not support EditOnEnter mode. How to fix this so that child DataGrid does not require additional click to start cell edit ?

    Andrus.

    Monday, December 14, 2009 2:16 PM
  • Your question/problem does not look too difficult. As long as the datasource of both parent and child datagrid are different, you really do not have to create a new instance of pagedcollectionview in the parent selection changed event.

    Can you please put some pieces of XAML and code behind to give us a better idea?

    Monday, December 14, 2009 3:51 PM
  • Quick sample with code behind which should be in ViewModel.

     

     

    "clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"  x:Class="SilverlightApplication2.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
        mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480"&gt;
        <StackPanel x:Name="LayoutRoot"&gt;
            <data:DataGrid ItemsSource="{Binding Path=CompaniesView}" SelectedItem="{Binding Path=SelectedCompany, Mode=TwoWay}"&gt;</data:DataGrid>
            <data:DataGrid ItemsSource="{Binding Path=EmployeesView}">
        
    
     
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using System.Windows.Data;
    
    namespace SilverlightApplication2
    {
        public partial class MainPage : UserControl
        {
            public List Employees = new List();
            public List Companies = new List();
            private PagedCollectionView employeesView = null;
            private PagedCollectionView companiesView = null;
            public MainPage()
            {
                InitializeComponent();
                this.DataContext = this;
                Companies.Add(new Company { Id = 1, Name = "CompanyA" });
                Companies.Add(new Company { Id = 2, Name = "CompanyB" });
    
                Employees.Add(new Employee { Id = 1, Name = "EmployeeA-A", CompanyId = 1 });
                Employees.Add(new Employee { Id = 2, Name = "EmployeeB-A", CompanyId = 1 });
                Employees.Add(new Employee { Id = 3, Name = "EmployeeC-A", CompanyId = 1 });
    
                Employees.Add(new Employee { Id = 4, Name = "EmployeeA-B", CompanyId = 2 });
                Employees.Add(new Employee { Id = 5, Name = "EmployeeB-B", CompanyId = 2 });
                Employees.Add(new Employee { Id = 6, Name = "EmployeeC-B", CompanyId = 2 });
    
            }
    
            public PagedCollectionView EmployeesView
            {
                get
                {
                    employeesView = new PagedCollectionView(Employees);
                    employeesView.Filter = new Predicate<object>(ShowCompanySpecific);
                    return employeesView;
                }
            }
    
            public bool ShowCompanySpecific(object t)
            {
                Employee employee = t as Employee;
                if (this.SelectedCompany == null)
                {
                    return false;
                }
                else
                {
                    return employee.CompanyId == SelectedCompany.Id ? true : false;
                }
            }
    
            public PagedCollectionView CompaniesView
            {
                get { companiesView = new PagedCollectionView(Companies); return companiesView; }
            }
    
            private Company selectedCompany;
            public Company SelectedCompany
            {
                get { return selectedCompany; }
                set
                {
                    selectedCompany = value;
                    employeesView.Refresh();
                }
            }
    
        }
    
        public class Employee
        {
            /// <summary>Id.</summary>
            public int Id { get; set; }
    
            /// <summary>Name</summary>
            public string Name { get; set; }
    
            public int CompanyId { get; set; }
        }
    
        public class Company
        {
            /// <summary>Id.</summary>
            public int Id { get; set; }
    
            /// <summary>Name</summary>
            public string Name { get; set; }
        }
    }
    
      

     

     

    Monday, December 14, 2009 4:31 PM
  • Steps to reproduce the issue:

    1. Run code below or run solution from http://cid-69f11148404c9c0e.skydrive.live.com/self.aspx/.Public/MasterChilddatagridException.zip

    2. Click in CompanyA
    3. Click EmployeeA-A
    4. Click in CompanyB

     Observed: InvalidOperationException: Refresh' is not allowed during an AddNew or EditItem transaction.

    How to fix ?

    Andrus.

     
    <UserControl x:Class="MasterChilddatagridException.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"
    xmlns:MasterChilddatagridException="clr-namespace:MasterChilddatagridException"
        >
        <StackPanel x:Name="LayoutRoot">
            <MasterChilddatagridException:DataGridBase ItemsSource="{Binding Path=CompaniesView}" SelectedItem="{Binding Path=SelectedCompany, Mode=TwoWay}"/>
            <MasterChilddatagridException:DataGridBase ItemsSource="{Binding Path=EmployeesView}"/>
        </StackPanel>
    </UserControl>
    
        

     
     

     

    using System;
    using System.Collections.Generic;
    using System.Windows.Controls;
    using System.Windows.Data;
    
    // Steps to reproduce:
    // 1. click in CompanyA
    // 2. Click EmployeeA-A
    // 3. click in CompanyB
    
    // Observed:
    //System.InvalidOperationException was unhandled by user code
    //  Message="'Refresh' is not allowed during an AddNew or EditItem transaction."
    //  StackTrace:
    //       at System.Windows.Data.PagedCollectionView.Refresh()
    //       at MasterChilddatagridException.MainPage.set_SelectedCompany(Company value)
    //  InnerException: 
    
    namespace MasterChilddatagridException
    {
    
        public partial class MainPage : UserControl
        {
            public List Employees = new List();
            public List Companies = new List();
            PagedCollectionView employeesView;
            PagedCollectionView companiesView;
    
            public MainPage()
            {
                InitializeComponent();
                DataContext = this;
                Companies.Add(new Company { Id = 1, Name = "CompanyA" });
                Companies.Add(new Company { Id = 2, Name = "CompanyB" });
    
                Employees.Add(new Employee { Id = 1, Name = "EmployeeA-A", CompanyId = 1 });
                Employees.Add(new Employee { Id = 2, Name = "EmployeeB-A", CompanyId = 1 });
                Employees.Add(new Employee { Id = 3, Name = "EmployeeC-A", CompanyId = 1 });
    
                Employees.Add(new Employee { Id = 4, Name = "EmployeeA-B", CompanyId = 2 });
                Employees.Add(new Employee { Id = 5, Name = "EmployeeB-B", CompanyId = 2 });
                Employees.Add(new Employee { Id = 6, Name = "EmployeeC-B", CompanyId = 2 });
    
            }
    
            public PagedCollectionView EmployeesView
            {
                get
                {
                    employeesView = new PagedCollectionView(Employees);
                    employeesView.Filter = new Predicate<object>(ShowCompanySpecific);
                    return employeesView;
                }
            }
    
            public bool ShowCompanySpecific(object t)
            {
                Employee employee = t as Employee;
                if (this.SelectedCompany == null)
                {
                    return false;
                }
                else
                {
                    return employee.CompanyId == SelectedCompany.Id ? true : false;
                }
            }
    
            public PagedCollectionView CompaniesView
            {
                get { companiesView = new PagedCollectionView(Companies); return companiesView; }
            }
    
            Company selectedCompany;
            public Company SelectedCompany
            {
                get { return selectedCompany; }
                set
                {
                    selectedCompany = value;
                    employeesView.Refresh();
                }
            }
    
        }
    
        public class Employee
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public int CompanyId { get; set; }
        }
    
        public class Company
        {
            public int Id { get; set; }
            public string Name { get; set; }
        }
    
    
        public class DataGridBase : DataGrid
        {
            protected override void OnCurrentCellChanged(EventArgs e)
            {
                base.OnCurrentCellChanged(e);
                BeginEdit();
            }
    
            protected override void OnSelectionChanged(SelectionChangedEventArgs e)
            {
                base.OnSelectionChanged(e);
                BeginEdit();
            }
        }
    }
     
    Tuesday, December 15, 2009 9:53 AM
  • Try to cancel your changes or commit your changes after you've added those details in your constructor.

    Tuesday, December 15, 2009 11:19 AM
  • Here is how the SelectedCompany property looks like now.

     

     private Company selectedCompany;
            public Company SelectedCompany
            {
                get { return selectedCompany; }
                set
                {
                    selectedCompany = value;
                    if (employeesView.CurrentEditItem != null)
                    {
                        if (MessageBox.Show("Save changes before navigating to other record?", "Save Pending", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
                        {
                            employeesView.CommitEdit();
                        }
                        else
                        {
                            employeesView.CancelEdit();
                        }
                    }               
                    
                    employeesView.Refresh();
                }
            }
    

     

    If you don't want the record to go into edit mode when you click on it, set the IsReadOnly property of the DataGrid to True. I have not tested it but it should take care of the problem.

    Tuesday, December 15, 2009 1:11 PM
  • I need to edit data immediately, without additional clicks or keypresses. So I think DataGrid should go to edit mode automatically always. I need also to save data to DataGrid without promp. I changed SelectedProperty to

            public Company SelectedCompany
            {
                get { return selectedCompany; }
                set
                {
                    selectedCompany = value;
                    if (employeesView.CurrentEditItem != null)
                        employeesView.CommitEdit();
                    employeesView.Refresh();
                }
            }

    I also added

                employeesView.CommitNew ();
                companiesView.CommitNew();
                employeesView.CommitEdit();
                companiesView.CommitEdit();

    code is below.

    Using steps from my previous message exception below occurs.

    How to fix ?

    Andrus.

    System.NullReferenceException was unhandled by user code
      Message="Object reference not set to an instance of an object."
      StackTrace:
           at System.Windows.Controls.DataGrid.EndCellEdit(DataGridEditAction editAction, Boolean exitEditingMode, Boolean keepFocus, Boolean raiseEvents)
           at System.Windows.Controls.DataGrid.CancelEdit(DataGridEditingUnit editingUnit, Boolean raiseEvents)
           at System.Windows.Controls.DataGrid.SetCurrentCellCore(Int32 columnIndex, Int32 slot, Boolean commitEdit, Boolean endRowEdit)
           at System.Windows.Controls.DataGrid.OnRemovingElement(Int32 slotDeleted)
           at System.Windows.Controls.DataGrid.RemoveElementAt(Int32 slot, Object item, Boolean isRow)
           at System.Windows.Controls.DataGrid.RemoveRowAt(Int32 rowIndex, Object item)
           at System.Windows.Controls.DataGridDataConnection.NotifyingDataSource_CollectionChanged(Object sender, NotifyCollectionChangedEventArgs e)
           at System.Windows.Data.PagedCollectionView.OnCollectionChanged(NotifyCollectionChangedEventArgs args)
           at System.Windows.Data.PagedCollectionView.CommitEdit()
           at MasterChilddatagridException.MainPage.set_SelectedCompany(Company value)

     

    using System;
    using System.Collections.Generic;
    using System.Windows.Controls;
    using System.Windows.Data;
    
    namespace MasterChilddatagridException
    {
    
        public partial class MainPage : UserControl
        {
            public List Employees = new List();
            public List Companies = new List();
            PagedCollectionView employeesView;
            PagedCollectionView companiesView;
    
            public MainPage()
            {
                InitializeComponent();
                DataContext = this;
                Companies.Add(new Company { Id = 1, Name = "CompanyA" });
                Companies.Add(new Company { Id = 2, Name = "CompanyB" });
    
                Employees.Add(new Employee { Id = 1, Name = "EmployeeA-A", CompanyId = 1 });
                Employees.Add(new Employee { Id = 2, Name = "EmployeeB-A", CompanyId = 1 });
                Employees.Add(new Employee { Id = 3, Name = "EmployeeC-A", CompanyId = 1 });
    
                Employees.Add(new Employee { Id = 4, Name = "EmployeeA-B", CompanyId = 2 });
                Employees.Add(new Employee { Id = 5, Name = "EmployeeB-B", CompanyId = 2 });
                Employees.Add(new Employee { Id = 6, Name = "EmployeeC-B", CompanyId = 2 });
            }
    
            public PagedCollectionView EmployeesView
            {
                get
                {
                    employeesView = new PagedCollectionView(Employees);
                    employeesView.Filter = new Predicate<object>(ShowCompanySpecific);
                    employeesView.CommitNew();
                    employeesView.CommitEdit();
                    return employeesView;
                }
            }
    
            public bool ShowCompanySpecific(object t)
            {
                Employee employee = t as Employee;
                if (this.SelectedCompany == null)
                {
                    return false;
                }
                else
                {
                    return employee.CompanyId == SelectedCompany.Id ? true : false;
                }
            }
    
            public PagedCollectionView CompaniesView
            {
                get
                {
                    companiesView = new PagedCollectionView(Companies);
                    companiesView.CommitNew();
                    companiesView.CommitEdit();
                    return companiesView;
                }
            }
    
            Company selectedCompany;
            public Company SelectedCompany
            {
                get { return selectedCompany; }
                set
                {
                    selectedCompany = value;
                    if (employeesView.CurrentEditItem != null)
                    {
                        //if (MessageBox.Show("Save changes before navigating to other record?", "Save Pending", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
                        //{
                        employeesView.CommitEdit();
                        //}
                        //else
                        //{
                        //    employeesView.CancelEdit();
                        //}
                    }
    
                    employeesView.Refresh();
                }
            }
    
    
        }
    
        public class Employee
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public int CompanyId { get; set; }
        }
    
        public class Company
        {
            public int Id { get; set; }
            public string Name { get; set; }
        }
    
    
        public class DataGridBase : DataGrid
        {
            protected override void OnCurrentCellChanged(EventArgs e)
            {
                base.OnCurrentCellChanged(e);
                BeginEdit();
            }
    
            protected override void OnSelectionChanged(SelectionChangedEventArgs e)
            {
                base.OnSelectionChanged(e);
                BeginEdit();
            }
        }
    }
     
    Wednesday, December 16, 2009 6:01 AM
  • You should not make an explicit call to BeginEdit() on cell changed or selectionchanged. The grid will be in edit mode if the user tries to edit any field. A BeginEdit call is unnecessarily making the object dirty. But its up to you.

    The object reference exception is simple enough to fix or debug if you look at the stack trace or debug.

    Keep in mind that its always a good practice to check if the object is not null before you perform any operation on it. In your case I think because you added the four commit statements one after the another it is throwing the object reference exception. Before refereshing the employeesView, do CommitEdit() if there is an edit object and do CommitNew() if there is a new object. The SelectedCompany property looks like:

     

     public Company SelectedCompany
            {
                get { return selectedCompany; }
                set
                {
                    selectedCompany = value;
                    if (employeesView.CurrentEditItem != null)
                    {
                        employeesView.CommitEdit();
                    }
                    if (employeesView.CurrentAddItem != null)
                    {
                        employeesView.CommitNew();
                    }        
                    employeesView.Refresh();
                }
            }
     Apply the same logic for companiesView too and in EmployeesView property.
    Wednesday, December 16, 2009 1:39 PM
  • You should not make an explicit call to BeginEdit() on cell changed or selectionchanged. The grid will be in edit mode if the user tries to edit any field

    If BeginEdit()s are removed, editing data requires extra click after cell becomes active. This makes data entry too slow and is not acceptable. How to allow fast data entry without BeginEdit() calls ?

    I added your code using code below but same exception

    System.NullReferenceException was unhandled by user code
      Message="Object reference not set to an instance of an object."
      StackTrace:
           at System.Windows.Controls.DataGrid.EndCellEdit(DataGridEditAction editAction, Boolean exitEditingMode, Boolean keepFocus, Boolean raiseEvents)
           at System.Windows.Controls.DataGrid.CancelEdit(DataGridEditingUnit editingUnit, Boolean raiseEvents)
           at System.Windows.Controls.DataGrid.SetCurrentCellCore(Int32 columnIndex, Int32 slot, Boolean commitEdit, Boolean endRowEdit)
           at System.Windows.Controls.DataGrid.OnRemovingElement(Int32 slotDeleted)
           at System.Windows.Controls.DataGrid.RemoveElementAt(Int32 slot, Object item, Boolean isRow)
           at System.Windows.Controls.DataGrid.RemoveRowAt(Int32 rowIndex, Object item)
           at System.Windows.Controls.DataGridDataConnection.NotifyingDataSource_CollectionChanged(Object sender, NotifyCollectionChangedEventArgs e)
           at System.Windows.Data.PagedCollectionView.OnCollectionChanged(NotifyCollectionChangedEventArgs args)
           at System.Windows.Data.PagedCollectionView.CommitEdit()
           at MasterChilddatagridException.MainPage.set_SelectedCompany(Company value)

    occurs at line

    employeesView.CommitEdit();
     

    How to fix it so that data can edited on single click/on cell entry ?

    Andrus.

     

    using System;
    using System.Collections.Generic;
    using System.Windows.Controls;
    using System.Windows.Data;
    
    namespace MasterChilddatagridException
    {
    
        public partial class MainPage : UserControl
        {
            public List Employees = new List();
            public List Companies = new List();
            PagedCollectionView employeesView;
            PagedCollectionView companiesView;
    
            public MainPage()
            {
                InitializeComponent();
                DataContext = this;
                Companies.Add(new Company { Id = 1, Name = "CompanyA" });
                Companies.Add(new Company { Id = 2, Name = "CompanyB" });
    
                Employees.Add(new Employee { Id = 1, Name = "EmployeeA-A", CompanyId = 1 });
                Employees.Add(new Employee { Id = 2, Name = "EmployeeB-A", CompanyId = 1 });
                Employees.Add(new Employee { Id = 3, Name = "EmployeeC-A", CompanyId = 1 });
    
                Employees.Add(new Employee { Id = 4, Name = "EmployeeA-B", CompanyId = 2 });
                Employees.Add(new Employee { Id = 5, Name = "EmployeeB-B", CompanyId = 2 });
                Employees.Add(new Employee { Id = 6, Name = "EmployeeC-B", CompanyId = 2 });
            }
    
            public PagedCollectionView EmployeesView
            {
                get
                {
                    employeesView = new PagedCollectionView(Employees);
                    employeesView.Filter = new Predicate<object>(ShowCompanySpecific);
                    return employeesView;
                }
            }
    
            public bool ShowCompanySpecific(object t)
            {
                Employee employee = t as Employee;
                if (this.SelectedCompany == null)
                {
                    return false;
                }
                else
                {
                    return employee.CompanyId == SelectedCompany.Id ? true : false;
                }
            }
    
            public PagedCollectionView CompaniesView
            {
                get
                {
                    companiesView = new PagedCollectionView(Companies);
                    return companiesView;
                }
            }
    
            Company selectedCompany;
            public Company SelectedCompany
            {
                get { return selectedCompany; }
                set
                {
                    selectedCompany = value;
                    if (employeesView.CurrentEditItem != null)
                        employeesView.CommitEdit();
                    if (employeesView.CurrentAddItem != null)
                        employeesView.CommitNew();
                    employeesView.Refresh();
                }
            }
    
        }
    
        public class Employee
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public int CompanyId { get; set; }
        }
    
        public class Company
        {
            public int Id { get; set; }
            public string Name { get; set; }
        }
    
    
        public class DataGridBase : DataGrid
        {
            protected override void OnCurrentCellChanged(EventArgs e)
            {
                base.OnCurrentCellChanged(e);
                BeginEdit();
            }
    
            protected override void OnSelectionChanged(SelectionChangedEventArgs e)
            {
                base.OnSelectionChanged(e);
                BeginEdit();
            }
        }
    }
     
    Wednesday, December 16, 2009 2:14 PM
  • Please send me your version of files in zipped format and I will send the fix.

    Wednesday, December 16, 2009 2:25 PM
  • Sorry didn't get a chance to look at. I will reply today.

    Thursday, December 17, 2009 1:22 PM
  • Thank you. I have tried workarounds like using DataGrid CommitEdit(), Dispatcher.BeginInvoke etc. without success.

    Havent found any way to use PagedCollectionView with immediate editing in DataGrid.

    Andrus.

    Thursday, December 17, 2009 1:30 PM
  • Please replace your code behind with the below code. I have not spent more than 20 minutes. I know that the explicit call to BeginEdit is causing the problem but I have not spent time to find how to go to edit mode without calling BeginEdit.

    If the below solution works then we can do it in a better view model way because this is not the ideal way to do it. Please give it a try to see if it works on your end. I tried it and see no more refresh issues when changing company or employee data. I did see an object reference exception which looked like an internal grid exception but was not able to reproduce it in the last few tries.

      

    using System;
    using System.Collections.Generic;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Diagnostics;
    
    namespace MasterChilddatagridException
    {
    
        public partial class MainPage : UserControl
        {
            public List Employees = new List();
            public List Companies = new List();
            PagedCollectionView employeesView;
            PagedCollectionView companiesView;
    
            public MainPage()
            {
                InitializeComponent();
                DataContext = this;
                Companies.Add(new Company { Id = 1, Name = "CompanyA" });
                Companies.Add(new Company { Id = 2, Name = "CompanyB" });
    
                Employees.Add(new Employee { Id = 1, Name = "EmployeeA-A", CompanyId = 1 });
                Employees.Add(new Employee { Id = 2, Name = "EmployeeB-A", CompanyId = 1 });
                Employees.Add(new Employee { Id = 3, Name = "EmployeeC-A", CompanyId = 1 });
    
                Employees.Add(new Employee { Id = 4, Name = "EmployeeA-B", CompanyId = 2 });
                Employees.Add(new Employee { Id = 5, Name = "EmployeeB-B", CompanyId = 2 });
                Employees.Add(new Employee { Id = 6, Name = "EmployeeC-B", CompanyId = 2 });
            }
    
            public PagedCollectionView EmployeesView
            {
                get
                {
                    employeesView = new PagedCollectionView(Employees);
                    employeesView.CurrentChanging += new System.ComponentModel.CurrentChangingEventHandler(employeesView_CurrentChanging);
                    employeesView.Filter = new Predicate<object>(ShowCompanySpecific);
                    return employeesView;
                }
            }
    
            void employeesView_CurrentChanging(object sender, System.ComponentModel.CurrentChangingEventArgs e)
            {
                UpdateAll();
            }
            void companiesView_CurrentChanged(object sender, EventArgs e)
            {
                UpdateAll();
                employeesView.Refresh();
    
            }
    
            void companiesView_CurrentChanging(object sender, System.ComponentModel.CurrentChangingEventArgs e)
            {
                UpdateAll();
            }
    
    
            public bool ShowCompanySpecific(object t)
            {
                Employee employee = t as Employee;
                if (companiesView.CurrentItem  == null || employee == null)
                {
                    return false;
                }
                else
                {
                    return employee.CompanyId == ((Company)companiesView.CurrentItem).Id ? true : false;
                }
            }
    
            public PagedCollectionView CompaniesView
            {
                get
                {
                    companiesView = new PagedCollectionView(Companies);
                    companiesView.CurrentChanging += new System.ComponentModel.CurrentChangingEventHandler(companiesView_CurrentChanging);
                    companiesView.CurrentChanged += new EventHandler(companiesView_CurrentChanged);
                    return companiesView;
                }
            }
    
           
            private void UpdateAll()
            {
                UpdateEmployeesView();
                UpdateCompaniesView();
                UpdateEmployeesView();
               
            }
            private void UpdateEmployeesView()
            {
                if (employeesView.IsEditingItem == true)
                {
                    employeesView.CommitEdit();
                }
                if (employeesView.IsAddingNew)
                {
                    employeesView.CommitNew();
                }
            }
    
            private void UpdateCompaniesView() 
            {
                if (companiesView.IsEditingItem == true)
                {
                    companiesView.CommitEdit();
                }
                if (companiesView.IsAddingNew)
                {
                    companiesView.CommitNew();
                }
            }
    
    
            Company selectedCompany;
            public Company SelectedCompany
            {
                get { return selectedCompany; }
                set
                {
                    selectedCompany = value;
                }
            }
    
        }
    
        public class Employee
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public int CompanyId { get; set; }
        }
    
        public class Company
        {
            public int Id { get; set; }
            public string Name { get; set; }
        }
    
    
        public class DataGridBase : DataGrid
        {       
            protected override void OnSelectionChanged(SelectionChangedEventArgs e)
            {            
                base.OnSelectionChanged(e);            
                BeginEdit();
            }
        }
    }
     
    Thursday, December 17, 2009 3:32 PM
  • I found the following issues in this code:

    1. NullReferenceException with exactly the same stact trace as in my samples occurs during editing: 

    Message: System.NullReferenceException: Object reference not set to an instance of an object.
       at System.Windows.Controls.DataGrid.PreparingCellForEditPrivate(FrameworkElement editingElement)
       at System.Windows.Controls.DataGrid.EditingElement_Loaded(Object sender, RoutedEventArgs e)
       at System.Windows.CoreInvokeHandler.InvokeEventHandler(Int32 typeIndex, Delegate handlerDelegate, Object sender, Object args)
       at MS.Internal.JoltHelper.FireEvent(IntPtr unmanagedObj, IntPtr unmanagedObjArgs, Int32 argsTypeIndex, String eventName)    

    2. Pressing right arrow in Name column does not start edit mode in CompanyId column. This is because the following lineas are removed from code:

    protected override void OnCurrentCellChanged(EventArgs e)
    {
       base.OnCurrentCellChanged(e);
       BeginEdit();
    }

    How to fix those issues ?

    Andrus.

    Thursday, December 17, 2009 4:02 PM
  • Okay another try. I removed the BeginEdit totally this time. Inorder to give the user the experience to sign click and edit, I have modified the xaml and provided the celleditingtemplates for the columns. I have not added the celltemplates as we don't need it. In the celleditingtemplates there is a textbox and I have kept the background to transparent and BorderThickness to 0 to show it like a textblock. When the user clicks on the cell the focus directly goes to the TextBox and the tab keys work too when navigating inside grids. See if we can live with the solution? If not, let me think about it more.

    I have put the code behind same as what we originaly had.

    The code behind looks like:

    using System;
    using System.Collections.Generic;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Diagnostics;
    
    namespace MasterChilddatagridException
    {
    
        public partial class MainPage : UserControl
        {
            public List Employees = new List();
            public List Companies = new List();
            PagedCollectionView employeesView;
            PagedCollectionView companiesView;
    
            public MainPage()
            {
                InitializeComponent();
                DataContext = this;
                Companies.Add(new Company { Id = 1, Name = "CompanyA" });
                Companies.Add(new Company { Id = 2, Name = "CompanyB" });
    
                Employees.Add(new Employee { Id = 1, Name = "EmployeeA-A", CompanyId = 1 });
                Employees.Add(new Employee { Id = 2, Name = "EmployeeB-A", CompanyId = 1 });
                Employees.Add(new Employee { Id = 3, Name = "EmployeeC-A", CompanyId = 1 });
    
                Employees.Add(new Employee { Id = 4, Name = "EmployeeA-B", CompanyId = 2 });
                Employees.Add(new Employee { Id = 5, Name = "EmployeeB-B", CompanyId = 2 });
                Employees.Add(new Employee { Id = 6, Name = "EmployeeC-B", CompanyId = 2 });
            }
    
            public PagedCollectionView EmployeesView
            {
                get
                {
                    employeesView = new PagedCollectionView(Employees);               
                    employeesView.Filter = new Predicate<object>(ShowCompanySpecific);
                    return employeesView;
                }
            }     
    
    
            public bool ShowCompanySpecific(object t)
            {
                Employee employee = t as Employee;
                if (companiesView.CurrentItem  == null || employee == null)
                {
                    return false;
                }
                else
                {
                    return employee.CompanyId == ((Company)companiesView.CurrentItem).Id ? true : false;
                }
            }
    
            public PagedCollectionView CompaniesView
            {
                get
                {
                    companiesView = new PagedCollectionView(Companies);               
                    return companiesView;
                }
            }
    
           
            private void UpdateAll()
            {
                UpdateEmployeesView();
                UpdateCompaniesView();
                UpdateEmployeesView();
               
            }
            private void UpdateEmployeesView()
            {
               
                    if (employeesView.IsEditingItem == true)
                    {
                        employeesView.CommitEdit();
                    }
                    if (employeesView.IsAddingNew)
                    {
                        employeesView.CommitNew();
                    }
                
            }
    
            private void UpdateCompaniesView() 
            {
              
                    if (companiesView.IsEditingItem == true)
                    {
                        companiesView.CommitEdit();
                    }
                    if (companiesView.IsAddingNew)
                    {
                        companiesView.CommitNew();
                    }
                
            }
    
    
            Company selectedCompany;
            public Company SelectedCompany
            {
                get { return selectedCompany; }
                set
                {
                    selectedCompany = value;
                    UpdateEmployeesView();
                    employeesView.Refresh();
                }
            }
    
        }
    
        public class Employee
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public int CompanyId { get; set; }
        }
    
        public class Company
        {
            public int Id { get; set; }
            public string Name { get; set; }
        }
    
    
        public class DataGridBase : DataGrid
        {       
            //protected override void OnSelectionChanged(SelectionChangedEventArgs e)
            //{            
            //    base.OnSelectionChanged(e);
            //    try
            //    {
            //        BeginEdit();
            //    }
            //    catch { }
                
            //}
            //protected override void OnCurrentCellChanged(EventArgs e)
            //{
            //    base.OnCurrentCellChanged(e);
            //    try
            //    {
            //        BeginEdit();
            //    }
            //    catch { }
            //}
    
        }
    }
     

    The xaml looks like:

    <UserControl x:Class="MasterChilddatagridException.MainPage"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"

    xmlns:MasterChilddatagridException="clr-namespace:MasterChilddatagridException"

    >

     

    <StackPanel x:Name="LayoutRoot">

    <MasterChilddatagridException:DataGridBase ItemsSource="{Binding Path=CompaniesView}" SelectedItem="{Binding Path=SelectedCompany, Mode=TwoWay}" AutoGenerateColumns="False">

    <MasterChilddatagridException:DataGridBase.Columns>

    <data:DataGridTemplateColumn Header="Id">

    <data:DataGridTemplateColumn.CellEditingTemplate>

    <DataTemplate>

    <TextBox Text="{Binding Path=Id, Mode=TwoWay}" Background="Transparent" BorderThickness="0" HorizontalAlignment="Stretch" VerticalAlignment="Center"/>

    </DataTemplate>

    </data:DataGridTemplateColumn.CellEditingTemplate>

    </data:DataGridTemplateColumn>

    <data:DataGridTemplateColumn Header="Name">

    <data:DataGridTemplateColumn.CellEditingTemplate>

    <DataTemplate>

    <TextBox Text="{Binding Path=Name, Mode=TwoWay}" Background="Transparent" BorderThickness="0" HorizontalAlignment="Stretch" VerticalAlignment="Center"/>

    </DataTemplate>

    </data:DataGridTemplateColumn.CellEditingTemplate>

    </data:DataGridTemplateColumn>

    </MasterChilddatagridException:DataGridBase.Columns>

    </MasterChilddatagridException:DataGridBase>

    <MasterChilddatagridException:DataGridBase ItemsSource="{Binding Path=EmployeesView}" AutoGenerateColumns="False">

    <MasterChilddatagridException:DataGridBase.Columns>

    <data:DataGridTemplateColumn Header="Id">

    <data:DataGridTemplateColumn.CellEditingTemplate>

    <DataTemplate>

    <TextBox Text="{Binding Path=Id, Mode=TwoWay}" Background="Transparent" BorderThickness="0" HorizontalAlignment="Stretch" VerticalAlignment="Center"/>

    </DataTemplate>

    </data:DataGridTemplateColumn.CellEditingTemplate>

    </data:DataGridTemplateColumn>

    <data:DataGridTemplateColumn Header="Name">

    <data:DataGridTemplateColumn.CellEditingTemplate>

    <DataTemplate>

    <TextBox Text="{Binding Path=Name, Mode=TwoWay}" Background="Transparent" BorderThickness="0" HorizontalAlignment="Stretch" VerticalAlignment="Center"/>

    </DataTemplate>

    </data:DataGridTemplateColumn.CellEditingTemplate>

    </data:DataGridTemplateColumn>

    <data:DataGridTemplateColumn Header="Company Id">

    <data:DataGridTemplateColumn.CellEditingTemplate>

    <DataTemplate>

    <TextBox Text="{Binding Path=CompanyId, Mode=TwoWay}" Background="Transparent" BorderThickness="0" HorizontalAlignment="Stretch" VerticalAlignment="Center"/>

    </DataTemplate>

    </data:DataGridTemplateColumn.CellEditingTemplate>

    </data:DataGridTemplateColumn>

    </MasterChilddatagridException:DataGridBase.Columns>

    </MasterChilddatagridException:DataGridBase>

    </StackPanel>

    </UserControl>

    Thursday, December 17, 2009 4:26 PM
  • I tried in this sample:

    1. Clicked in CompanyA

    2. Clicked in EmployeeA-A

    3. Pressed Down Arrow Key

    3. Typed some characters.

    Observed:

    Typed characters are lost.

    How to fix this ?

    Btw. Master DataGrid can use BeginEdit() without any isses, no need to remove BeginEdit() from it.

    How to implement immediate edit in child DataGrid ?

    Andrus.

    Friday, December 18, 2009 5:05 AM
  • If you edit a text in the grid, you might have to either hit enter or tab to update the source object. If you want to update the object as you type then create a TextBoxEx inheriting from TextBox and update the bound source on textchanged event because by default the TextBox's UpdataSourceTrigger is OnLostFocus.

    See if replacing the textbox with TextBoxEx fixes the problem.

    You decide if you want to use the BeginEdit or not. I have seen that you have to add extra code and handle some extra situations which are usually supported by default and otherwise we don't worry about them.

    The extended TextBox looks like:

    using System;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Ink;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using System.Windows.Data;
    
    namespace Controls
    {
        public class TextBoxEx:TextBox
        {
            private BindingExpression bindingExp;
            public TextBoxEx()
                : base()
            {
                this.TextChanged += new TextChangedEventHandler(OnTextChanged);
            }
            #region Properties
            public BindingExpression BindingExp
            {
                get
                {
                    if (bindingExp == null)
                    {
                        try
                        {
                            bindingExp = this.GetBindingBLOCKED EXPRESSION;
                        }
                        catch
                        {
                            throw new Exception("The binding is not valid for textbox: " + this.Name);
                        }
                    }
                    return bindingExp;
                }
    
            }
            #endregion
    
            #region Private Methods
            private void OnTextChanged(object sender, TextChangedEventArgs e)
            {
                BindingExp.UpdateSource();
            }
    
            #endregion
        }
    
    
    }
    
     
    Friday, December 18, 2009 12:42 PM
  • If you edit a text in the grid, you might have to either hit enter or tab to update the source object.

    This is exactly what I want and what our implementation does.

    See if replacing the textbox with TextBoxEx fixes the problem.

    It does not fix the problem. The issue is that TextBox does not receive typed characters in this case. DataGrid receives and eats those characters since there is no CellTemplate which processes them and CellEditTemplae is not activated automatically.

    TextBox starts receiving characters only after it is clicked. This click needs to be eliminated.

     

    I have seen that you have to add extra code and handle some extra situations which are usually supported by default

    I have added BeginEdit() to two events to support immediate editing when cell is clicked or when keyboard keys is used to receive focus. Your last solution does not start editing if keys are used to navigate into cell as described in testcase. How to fix this ?

    Andrus.

    Friday, December 18, 2009 1:20 PM
  • Revert your changes to what you had before introducing TextBoxEx. I understood now the problem with arrow keys.

    I will look at the solution.

    Friday, December 18, 2009 2:14 PM
  • Thank you. Maybe we can use BeginEdits() and can find safe way to refresh or re-create filtered child collection without using PagedCollectionView.Refresh()

    I posted also this issue as bug using your great sample code in

    http://forums.silverlight.net/forums/p/151457/337946.aspx

    Andrus.

    Friday, December 18, 2009 2:34 PM
  • I will look at the solution.

    Have you looked to the solution ? 

    Andrus.

    Friday, December 25, 2009 6:28 AM
  • Hi Kobruleht,

     I have been away from work. I will try to find something today.

    Monday, December 28, 2009 1:36 PM
  •  Thank you. As a last effort I stopped using PagedCollectionView and created filtered collection manually in parent DataGrid SelectionChanged:

    // _childGrid.DataSource.Modifieds type is IList
    var filtered = new List<EntityBase>();
    foreach (EntityBase i in _childGrid.DataSource.Modifieds)
        if (FilterChildRows(i))
               filtered.Add(i);
    _childGrid.ItemsSource = filtered;

    It this case if up or down arrow is hold down in parent DataGrid, moving to previous/next row is slow. Apparently this code takes lot of time to execute.

    Andrus.

    Monday, December 28, 2009 2:21 PM
  • I am not sure if the code will help our original task. You are setting the items source everytime in this code. May be thats the reason it is slow. The decision is up to you. You will also lose the selected row behavior when you reset the itemsource. The selected item is supported by default with collection view.

    Monday, December 28, 2009 2:26 PM
  • I do'nt know better solution. I will wait for yor solution. It is interesting to know how PagedCollectionView implements filtering. Maybe we can look into its code to implement fast filtering without changing ItemsSource or fix its behaviour.

    Andrus.

    Monday, December 28, 2009 3:04 PM
  • I have spent some time to find a solution to use keyboard left arrow, right arrow and tab keys to enable quick data entry on the grid but it does not work in my/our sample code above. When I set the focus on Companies grid and use tab key, it does move from one cell to another on the first row but after the last cell the focus moves to the first row of Employees grid. The correct behavior here would be that using tab key at the end of each row, the focus should move to next row if there is any.

    I even tried disabling the Employee grid but the focus still does not work as expected on Companies grid.

    In my other project I have just one grid which is bound to the page collection view and that works just fine. I am using the tab key to move focus from one cell to another and then when it reaches the last column/cell, it moves to another row.

    I will keep looking.

    Wednesday, January 06, 2010 1:51 PM
  • Thank you. Navigation may be customized using TabNavigation attribute of KeyDown event handler.
    You can add BeginEdit() calls to your application to make data entry keyboard firendly.

    I will continue waiting for your solution.

    Andrus.

    Wednesday, January 06, 2010 2:04 PM
  • Microsoft has posted suggestions to resolve those issues in

    https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=521531&wa=wsignin1.0

    How to to fix this code using those suggestions ?

    Andrus.

    Wednesday, January 13, 2010 4:39 AM
  • Cool. Let me give it a try.

    Friday, January 15, 2010 11:54 AM
  • How are things going ? Did you had opportunity to be in work and research this issue ?

    Sunday, January 24, 2010 12:34 PM