public void EnsureCurrentIndexSyncedAfterCollectionViewMovesToAfterLast()
        {
            DataFormApp_Standard dataFormApp = new DataFormApp_Standard();
            PagedCollectionView pcv = new PagedCollectionView(DataClassList.GetDataClassList(2, ListOperations.All));
            dataFormApp.dataForm.ItemsSource = pcv;

            this.EnqueueCallback(() =>
            {
                this.DataFormAppBase = dataFormApp;
            });

            this.AddToPanelAndWaitForLoad();

            this.EnqueueCallback(() =>
            {
                Assert.AreEqual(0, pcv.CurrentPosition);
                Assert.AreEqual(pcv[0], dataFormApp.dataForm.CurrentItem);
                this.ExpectCurrentItemChange();
                pcv.MoveCurrentToPosition(2);
            });

            this.WaitForCurrentItemChange();

            this.EnqueueCallback(() =>
            {
                Assert.AreEqual(2, pcv.CurrentPosition);
                Assert.AreEqual(2, dataFormApp.dataForm.CurrentIndex);
                Assert.IsNull(dataFormApp.dataForm.CurrentItem);
                this.ExpectCurrentItemChange();
                pcv.MoveCurrentToPosition(0);
            });

            this.WaitForCurrentItemChange();

            this.EnqueueCallback(() =>
            {
                this.ExpectCurrentItemChange();
                dataFormApp.dataForm.CurrentIndex = 2;
            });

            this.WaitForCurrentItemChange();

            this.EnqueueCallback(() =>
            {
                Assert.AreEqual(2, pcv.CurrentPosition);
                Assert.AreEqual(2, dataFormApp.dataForm.CurrentIndex);
                Assert.IsNull(dataFormApp.dataForm.CurrentItem);
            });

            this.EnqueueTestComplete();
        }
        public void MoveCurrencyToNullWhenAppending()
        {
            DataFormApp_Fields dataFormApp = new DataFormApp_Fields();

            List<DataClassWithValidation> dataClassList =
                new List<DataClassWithValidation>()
                {
                    new DataClassWithValidation()
                    {
                        StringProperty = "string 1"
                    }
                };

            PagedCollectionView pcv = new PagedCollectionView(dataClassList);

            this.EnqueueCallback(() =>
            {
                dataFormApp.dataForm.ItemsSource = pcv;
                this.DataFormAppBase = dataFormApp;
            });

            this.AddToPanelAndWaitForLoad();

            this.EnqueueCallback(() =>
            {
                this.ExpectCurrentItemChange();
                dataFormApp.dataForm.AddNewItem();
            });

            this.WaitForCurrentItemChange();

            this.EnqueueCallback(() =>
            {
                Assert.AreEqual(2, pcv.Count);
                this.ExpectCurrentItemChange();
                pcv.MoveCurrentToPosition(-1);
            });

            this.WaitForCurrentItemChange();

            this.EnqueueCallback(() =>
            {
                Assert.AreEqual(1, pcv.Count);
            });

            this.EnqueueTestComplete();
        }
        public void EnsureCollectionViewAtBeforeFirstIsMovedToFirst()
        {
            DataFormApp_Standard dataFormApp = new DataFormApp_Standard();
            PagedCollectionView cv = new PagedCollectionView(DataClassList.GetDataClassList(2, ListOperations.All));
            cv.MoveCurrentToPosition(-1);
            dataFormApp.dataForm.ItemsSource = cv;

            this.EnqueueCallback(() =>
            {
                this.DataFormAppBase = dataFormApp;
            });

            this.AddToPanelAndWaitForLoad();

            this.EnqueueCallback(() =>
            {
                Assert.AreEqual(0, cv.CurrentPosition);
            });

            this.EnqueueTestComplete();
        }
        public void ItemsSource()
        {
            Type propertyType = typeof(IEnumerable);
            bool expectGet = true;
            bool expectSet = true;
            bool hasSideEffects = true;

            DataGrid control = new DataGrid();
            TestPanel.Children.Add(control);
            Assert.IsNotNull(control);

            // Verify dependency property member
            FieldInfo fieldInfo = typeof(DataGrid).GetField("ItemsSourceProperty", BindingFlags.Static | BindingFlags.Public);
            Assert.AreEqual(typeof(DependencyProperty), fieldInfo.FieldType, "DataGrid.ItemsSourceProperty not expected type 'DependencyProperty'.");

            // Verify dependency property's value type
            DependencyProperty property = fieldInfo.GetValue(null) as DependencyProperty;

            Assert.IsNotNull(property);

            // 


            // Verify dependency property CLR property member
            PropertyInfo propertyInfo = typeof(DataGrid).GetProperty("ItemsSource", BindingFlags.Instance | BindingFlags.Public);
            Assert.IsNotNull(propertyInfo, "Expected CLR property DataGrid.ItemsSource does not exist.");
            Assert.AreEqual(propertyType, propertyInfo.PropertyType, "DataGrid.ItemsSource not expected type 'IEnumerable'.");

            // Verify getter/setter access
            Assert.AreEqual(expectGet, propertyInfo.CanRead, "Unexpected value for propertyInfo.CanRead.");
            Assert.AreEqual(expectSet, propertyInfo.CanWrite, "Unexpected value for propertyInfo.CanWrite.");

            // Verify that we set what we get
            if (expectSet) // if expectSet == false, this block can be removed
            {
                control.SelectionChanged += new SelectionChangedEventHandler(control_SelectionChanged);

                ObservableCollection<int> data1 = new ObservableCollection<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
                ObservableCollection<string> data2 = new ObservableCollection<string> { "zero", "one", "two" };
                ObservableCollection<double> data3 = new ObservableCollection<double> { 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9 };
                PagedCollectionView pcv1 = new PagedCollectionView(data1);
                PagedCollectionView pcv2 = new PagedCollectionView(data2);
                PagedCollectionView pcv3 = new PagedCollectionView(data3);

                this.EnqueueCallback(delegate
                {
                    control.ItemsSource = data1;
                });
                this.EnqueueYieldThread();
                
                this.EnqueueCallback(delegate
                {
                    Assert.AreEqual(data1, control.ItemsSource);
                    Assert.IsNull(control.SelectedItem, "No items should be selected by default if ItemsSource was not set to an ICollectionView");
                    Assert.AreEqual(-1, control.SelectedIndex, "No items should be selected by default if ItemsSource was not set to an ICollectionView");
                    Assert.AreEqual(0, control.CurrentColumnIndex, "The first cell should be current by default");
                    Assert.AreEqual(control.Columns[0], control.CurrentColumn, "The first cell should be current by default");

                    Assert.AreEqual(0, this._counter, "SelectionChanged should not have been raised yet");
                    Assert.IsNull(this._selectionChangedEventArgs, "SelectionChanged should not have been raised yet");

                    control.ItemsSource = data2;
                    control.SelectedIndex = 1;

                    // Force a CollectionChanged.Reset by adding and removing a GroupDescription, in order to
                    // verify that resetting the collection while a SelectionChanged event is pending will still work correctly.
                    Assert.IsNotNull(control.DataConnection.CollectionView);
                    control.DataConnection.CollectionView.GroupDescriptions.Add(new PropertyGroupDescription("Length"));
                    control.DataConnection.CollectionView.GroupDescriptions.Clear();
                });
                this.EnqueueYieldThread();

                this.EnqueueCallback(delegate
                {
                    Assert.AreEqual(data2, control.ItemsSource);
                    Assert.AreEqual(data2[1], control.SelectedItem, "Setting SelectedIndex after ItemsSource did not work");
                    Assert.AreEqual(1, control.SelectedIndex, "Setting SelectedIndex after ItemsSource did not work");
                    Assert.IsNotNull(this._selectionChangedEventArgs, "SelectionChanged should have been raised");
                    Assert.AreEqual(1, this._selectionChangedEventArgs.AddedItems.Count);
                    Assert.AreEqual(0, control.CurrentColumnIndex, "The first cell should be current by default");
                    Assert.AreEqual(control.Columns[0], control.CurrentColumn, "The first cell should be current by default");

                    Assert.AreEqual(1, this._counter, "SelectionChanged should have been raised");
                    Assert.IsNotNull(this._selectionChangedEventArgs, "SelectionChanged should have been raised");
                    Assert.IsNotNull(this._selectionChangedEventArgs.AddedItems);
                    Assert.AreEqual(1, this._selectionChangedEventArgs.AddedItems.Count, "A single item should have been added");
                    Assert.AreEqual(data2[1], this._selectionChangedEventArgs.AddedItems[0], "A single item should have been added");
                    Assert.IsNotNull(this._selectionChangedEventArgs.RemovedItems);
                    Assert.AreEqual(0, this._selectionChangedEventArgs.RemovedItems.Count, "No items should have been removed");

                    control.ItemsSource = data3;
                    control.SelectedItem = data3[3];
                });
                this.EnqueueYieldThread();

                this.EnqueueCallback(delegate
                {
                    Assert.AreEqual(data3, control.ItemsSource);
                    Assert.AreEqual(data3[3], control.SelectedItem, "Setting SelectedItem after ItemsSource did not work");
                    Assert.AreEqual(3, control.SelectedIndex, "Setting SelectedItem after ItemsSource did not work");
                    Assert.AreEqual(0, control.CurrentColumnIndex, "The first cell should be current by default");
                    Assert.AreEqual(control.Columns[0], control.CurrentColumn, "The first cell should be current by default");

                    Assert.AreEqual(2, this._counter, "SelectionChanged should have been raised");
                    Assert.IsNotNull(this._selectionChangedEventArgs, "SelectionChanged should have been raised");
                    Assert.IsNotNull(this._selectionChangedEventArgs.AddedItems);
                    Assert.AreEqual(1, this._selectionChangedEventArgs.AddedItems.Count, "A single item should have been added");
                    Assert.AreEqual(data3[3], this._selectionChangedEventArgs.AddedItems[0], "A single item should have been added");
                    Assert.IsNotNull(this._selectionChangedEventArgs.RemovedItems);
                    Assert.AreEqual(1, this._selectionChangedEventArgs.RemovedItems.Count, "A single item should have been removed");
                    Assert.AreEqual(data2[1], this._selectionChangedEventArgs.RemovedItems[0], "A single item should have been removed");

                    control.ItemsSource = pcv1;
                });
                this.EnqueueYieldThread();

                this.EnqueueCallback(delegate
                {
                    Assert.AreEqual(pcv1, control.ItemsSource);
                    Assert.AreEqual(pcv1[0], control.SelectedItem, "First item was not selected when setting ItemsSource to an ICollectionView");
                    Assert.AreEqual(0, control.SelectedIndex, "First item was not selected when setting ItemsSource to an ICollectionView");
                    Assert.AreEqual(0, control.CurrentColumnIndex, "The first cell should be current by default");
                    Assert.AreEqual(control.Columns[0], control.CurrentColumn, "The first cell should be current by default");

                    Assert.AreEqual(3, this._counter, "SelectionChanged should have been raised");
                    Assert.IsNotNull(this._selectionChangedEventArgs, "SelectionChanged should have been raised");
                    Assert.IsNotNull(this._selectionChangedEventArgs.AddedItems);
                    Assert.AreEqual(1, this._selectionChangedEventArgs.AddedItems.Count, "A single item should have been added");
                    Assert.AreEqual(pcv1[0], this._selectionChangedEventArgs.AddedItems[0], "A single item should have been added");
                    Assert.IsNotNull(this._selectionChangedEventArgs.RemovedItems);
                    Assert.AreEqual(1, this._selectionChangedEventArgs.RemovedItems.Count, "A single item should have been removed");
                    Assert.AreEqual(data3[3], this._selectionChangedEventArgs.RemovedItems[0], "A single item should have been removed");

                    pcv2.MoveCurrentToPosition(1);
                    control.ItemsSource = pcv2;
                });
                this.EnqueueYieldThread();

                this.EnqueueCallback(delegate
                {
                    Assert.AreEqual(pcv2, control.ItemsSource);
                    Assert.AreEqual(pcv2[1], control.SelectedItem, "CollectionView.CurrentItem was not selected by default");
                    Assert.AreEqual(1, control.SelectedIndex, "CollectionView.CurrentItem was not selected by default");
                    Assert.AreEqual(0, control.CurrentColumnIndex, "The first cell should be current by default");
                    Assert.AreEqual(control.Columns[0], control.CurrentColumn, "The first cell should be current by default");

                    Assert.AreEqual(4, this._counter, "SelectionChanged should have been raised");
                    Assert.IsNotNull(this._selectionChangedEventArgs, "SelectionChanged should have been raised");
                    Assert.IsNotNull(this._selectionChangedEventArgs.AddedItems);
                    Assert.AreEqual(1, this._selectionChangedEventArgs.AddedItems.Count, "A single item should have been added");
                    Assert.AreEqual(pcv2[1], this._selectionChangedEventArgs.AddedItems[0], "A single item should have been added");
                    Assert.IsNotNull(this._selectionChangedEventArgs.RemovedItems);
                    Assert.AreEqual(1, this._selectionChangedEventArgs.RemovedItems.Count, "A single item should have been removed");
                    Assert.AreEqual(pcv1[0], this._selectionChangedEventArgs.RemovedItems[0], "A single item should have been removed");

                    pcv3.MoveCurrentToPosition(-1);
                    control.ItemsSource = pcv3;
                });
                this.EnqueueYieldThread();

                this.EnqueueCallback(delegate
                {
                    Assert.AreEqual(pcv3, control.ItemsSource);
                    Assert.IsNull(control.SelectedItem, "No items should be selected if CollectionView.CurrentItem is null");
                    Assert.AreEqual(-1, control.SelectedIndex, "No items should be selected if CollectionView.CurrentItem is null");
                    Assert.AreEqual(-1, control.CurrentColumnIndex, "There should be no current cell if CollectionView.CurrentItem is null");
                    Assert.IsNull(control.CurrentColumn, "There should be no current cell if CollectionView.CurrentItem is null");

                    Assert.AreEqual(5, this._counter, "SelectionChanged should have been raised");
                    Assert.IsNotNull(this._selectionChangedEventArgs, "SelectionChanged should have been raised");
                    Assert.IsNotNull(this._selectionChangedEventArgs.AddedItems);
                    Assert.AreEqual(0, this._selectionChangedEventArgs.AddedItems.Count, "No items should have been added");
                    Assert.IsNotNull(this._selectionChangedEventArgs.RemovedItems);
                    Assert.AreEqual(1, this._selectionChangedEventArgs.RemovedItems.Count, "A single item should have been removed");
                    Assert.AreEqual(pcv2[1], this._selectionChangedEventArgs.RemovedItems[0], "A single item should have been removed");

                    control.ProcessDownKey();
                });
                this.EnqueueYieldThread();

                this.EnqueueCallback(delegate
                {
                    Assert.AreEqual(pcv3[0], control.SelectedItem, "The first item should be selected after pressing the down key");
                    Assert.AreEqual(0, control.SelectedIndex, "The first item should be selected after pressing the down key");
                    Assert.AreEqual(0, control.CurrentColumnIndex, "The first cell should be current after pressing the down key");
                    Assert.AreEqual(control.Columns[0], control.CurrentColumn, "The first cell should be current after pressing the down key");

                    Assert.AreEqual(6, this._counter, "SelectionChanged should have been raised");
                    Assert.IsNotNull(this._selectionChangedEventArgs, "SelectionChanged should have been raised");
                    Assert.IsNotNull(this._selectionChangedEventArgs.AddedItems);
                    Assert.AreEqual(1, this._selectionChangedEventArgs.AddedItems.Count, "A single item should have been added");
                    Assert.AreEqual(pcv3[0], this._selectionChangedEventArgs.AddedItems[0], "A single item should have been added");
                    Assert.IsNotNull(this._selectionChangedEventArgs.RemovedItems);
                    Assert.AreEqual(0, this._selectionChangedEventArgs.RemovedItems.Count, "No items should have been removed");
                });
            }

            // Verify dependency property callback
            if (hasSideEffects)
            {
                MethodInfo methodInfo = typeof(DataGrid).GetMethod("OnItemsSourcePropertyChanged", BindingFlags.Static | BindingFlags.NonPublic);
                Assert.IsNotNull(methodInfo, "Expected DataGrid.ItemsSource to have static, non-public side-effect callback 'OnItemsSourcePropertyChanged'.");

                // 
            }
            else
            {
                MethodInfo methodInfo = typeof(DataGrid).GetMethod("OnItemsSourcePropertyChanged", BindingFlags.Static | BindingFlags.NonPublic);
                Assert.IsNull(methodInfo, "Expected DataGrid.ItemsSource NOT to have static side-effect callback 'OnItemsSourcePropertyChanged'.");
            }

            this.EnqueueTestComplete();
        }