Пример #1
0
        /// <summary>
        /// INotifyCollectionChanged.CollectionChanged handler for updating DataGrid.SelectedItems when the source list changes
        /// </summary>
        private static void UpdateDataGridsOnSourceCollectionChanged(object source, NotifyCollectionChangedEventArgs collectionChangedArgs)
        {
            DataGridsAndInitiatedSelectionChange sourceListInfo = ListViewMultipleSelection.selectedItemsSources[source.GetHashCode()];

            // For each DataGrid that is bound to this list, is alive, and did not initate selection changes, update its selection
            sourceListInfo.InitiatedSelectionChange = true;
            IList sourceList = source as IList;

            Debug.Assert(sourceList != null, "SelectedItemsSource must be of type IList");
            ListView dataGrid = null;

            foreach (WeakReference dataGridReference in sourceListInfo.BoundDataGridReferences)
            {
                if (dataGridReference.IsAlive && !ListViewMultipleSelection.GetInitiatedSelectionChange(dataGridReference.Target as ListView))
                {
                    dataGrid = dataGridReference.Target as ListView;
                    UpdateDataGrid(dataGrid, sourceList, collectionChangedArgs);
                }
            }
            sourceListInfo.InitiatedSelectionChange = false;
        }
Пример #2
0
        /// <summary>
        /// Updates the items source registry when the SelectedItemsSource for a DataGrid changes
        /// </summary>
        private static void SelectedItemsSourceChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
        {
            ListView dataGrid            = sender as ListView;
            IList    selectedItemsSource = null;

            // Check if the app is setting the source to a new or different list, or if it is removing the binding
            if (args.NewValue != null)
            {
                selectedItemsSource = args.NewValue as IList;
                if (selectedItemsSource == null)
                {
                    throw new ArgumentException("The value for SelectedItemsSource must implement IList.");
                }

                INotifyCollectionChanged collection = args.NewValue as INotifyCollectionChanged;
                if (collection == null)
                {
                    throw new ArgumentException("The value for SelectedItemsSource must implement INotifyCollectionChanged.");
                }

                // Don't add the event handler if the DataGrid is not setting its SelectedItemsSource for the first time
                if (args.OldValue == null)
                {
                    // Sign up for changes to the DataGrid's selected items to enable a two-way binding effect
                    dataGrid.SelectionChanged += UpdateSourceListOnDataGridSelectionChanged;
                }

                // Track this DataGrid instance for the specified source list
                DataGridsAndInitiatedSelectionChange sourceListInfo = null;
                if (ListViewMultipleSelection.selectedItemsSources.TryGetValue(selectedItemsSource.GetHashCode(), out sourceListInfo))
                {
                    sourceListInfo.BoundDataGridReferences.Add(new WeakReference(dataGrid));
                }
                else
                {
                    // This is a new source collection
                    sourceListInfo = new DataGridsAndInitiatedSelectionChange()
                    {
                        InitiatedSelectionChange = false
                    };
                    sourceListInfo.BoundDataGridReferences.Add(new WeakReference(dataGrid));
                    ListViewMultipleSelection.selectedItemsSources.Add(selectedItemsSource.GetHashCode(), sourceListInfo);

                    // Sign up for changes to the source only on the first time the source is added
                    collection.CollectionChanged += UpdateDataGridsOnSourceCollectionChanged;
                }

                // Now force the DataGrid to update its SelectedItems to match the current
                // contents of the source list
                sourceListInfo.InitiatedSelectionChange = true;
                UpdateDataGrid(dataGrid, selectedItemsSource, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
                sourceListInfo.InitiatedSelectionChange = false;
            }
            else
            {
                // This DataGrid is removing its SelectedItems binding to any list
                dataGrid.SelectionChanged -= UpdateSourceListOnDataGridSelectionChanged;
                dataGrid.SelectedItems.Clear();
            }

            if (args.OldValue != null)
            {
                // Clean up the items source that was the old value

                // Remove the DataGrid from the source list's registry and remove the source list
                // if there are no more DataGrids bound to it.
                DataGridsAndInitiatedSelectionChange sourceListInfo = ListViewMultipleSelection.selectedItemsSources[args.OldValue.GetHashCode()];
                WeakReference dataGridReferenceNeedingRemoval       = null;
                foreach (WeakReference dataGridReference in sourceListInfo.BoundDataGridReferences)
                {
                    if (dataGridReference.IsAlive && (dataGridReference.Target == dataGrid))
                    {
                        dataGridReferenceNeedingRemoval = dataGridReference;
                        break;
                    }
                }
                sourceListInfo.BoundDataGridReferences.Remove(dataGridReferenceNeedingRemoval);
                if (sourceListInfo.BoundDataGridReferences.Count == 0)
                {
                    ListViewMultipleSelection.selectedItemsSources.Remove(args.OldValue.GetHashCode());

                    // Detach the event handlers and clear DataGrid.SelectedItems since the source is now null
                    INotifyCollectionChanged collection = args.OldValue as INotifyCollectionChanged;
                    if (collection != null)
                    {
                        collection.CollectionChanged -= UpdateDataGridsOnSourceCollectionChanged;
                    }
                }
            }
        }