This repository has been archived on 2024-01-02. You can view files and clone it, but cannot push or open issues or pull requests.
Sic06/FrameworkLocal/UIClient/DataGridTransform/DataGrid/Microsoft/Windows/Controls/ColumnHeaderCollection.cs

270 lines
7.8 KiB
C#

//---------------------------------------------------------------------------
//
// Copyright (C) Microsoft Corporation. All rights reserved.
//
//---------------------------------------------------------------------------
using System;
using System.Collections;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Diagnostics;
using System.Windows;
namespace ExtendedGrid.Microsoft.Windows.Controls
{
/// <summary>
/// Collection used as the ItemsSource of The DataGridColumnHeadersPresenter. This is a wrapper around the Column collection; each item
/// returns the corresponding Column.Header.
/// </summary>
internal class ColumnHeaderCollection : IEnumerable, INotifyCollectionChanged, IDisposable
{
public ColumnHeaderCollection(ObservableCollection<DataGridColumn> columns)
{
_columns = columns;
if (_columns != null)
{
_columns.CollectionChanged += OnColumnsChanged;
}
}
public DataGridColumn ColumnFromIndex(int index)
{
if (index >= 0 && index < _columns.Count)
{
return _columns[index];
}
return null;
}
#region Notification Propagation
/// <summary>
/// Called when the Header property on a Column changes. Causes us to fire a CollectionChanged event to specify that an item has been replaced.
/// </summary>
/// <param name="column"></param>
internal void NotifyHeaderPropertyChanged(DataGridColumn column, DependencyPropertyChangedEventArgs e)
{
Debug.Assert(e.Property == DataGridColumn.HeaderProperty, "We only want to know about the header property changing");
Debug.Assert(_columns.Contains(column));
NotifyCollectionChangedEventArgs args = new NotifyCollectionChangedEventArgs(
NotifyCollectionChangedAction.Replace,
e.NewValue,
e.OldValue,
_columns.IndexOf(column));
FireCollectionChanged(args);
}
#endregion
#region IDisposable Members
public void Dispose()
{
if (_columns != null)
{
_columns.CollectionChanged -= OnColumnsChanged;
}
}
#endregion
#region IEnumerable Members
public IEnumerator GetEnumerator()
{
return new ColumnHeaderCollectionEnumerator(_columns);
}
private class ColumnHeaderCollectionEnumerator : IEnumerator, IDisposable
{
public ColumnHeaderCollectionEnumerator(ObservableCollection<DataGridColumn> columns)
{
if (columns != null)
{
_columns = columns;
_columns.CollectionChanged += OnColumnsChanged;
}
_current = -1;
}
#region IEnumerator Members
public object Current
{
get
{
if (IsValid)
{
DataGridColumn column = _columns[_current];
if (column != null)
{
return column.Header;
}
return null;
}
throw new InvalidOperationException();
}
}
public bool MoveNext()
{
if (HasChanged)
{
throw new InvalidOperationException();
}
if (_columns != null && _current < _columns.Count - 1)
{
_current++;
return true;
}
return false;
}
public void Reset()
{
if (HasChanged)
{
throw new InvalidOperationException();
}
_current = -1;
}
#endregion
#region IDisposable Members
public void Dispose()
{
if (_columns != null)
{
_columns.CollectionChanged -= OnColumnsChanged;
}
}
#endregion
#region Helpers
private bool HasChanged
{
get
{
return _columnsChanged;
}
}
private bool IsValid
{
get
{
return _columns != null && _current >= 0 && _current < _columns.Count && !HasChanged;
}
}
private void OnColumnsChanged(object sender, NotifyCollectionChangedEventArgs e)
{
_columnsChanged = true;
}
#endregion
#region Data
private int _current;
private bool _columnsChanged;
private ObservableCollection<DataGridColumn> _columns;
#endregion
}
#endregion
#region INotifyCollectionChanged Members
/// <summary>
/// INotifyCollectionChanged CollectionChanged event
/// </summary>
public event NotifyCollectionChangedEventHandler CollectionChanged;
/// <summary>
/// Helper to raise a CollectionChanged event when the columns collection has changed
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OnColumnsChanged(object sender, NotifyCollectionChangedEventArgs e)
{
NotifyCollectionChangedEventArgs newArgs;
switch (e.Action)
{
case NotifyCollectionChangedAction.Add:
newArgs = new NotifyCollectionChangedEventArgs(e.Action, HeadersFromColumns(e.NewItems), e.NewStartingIndex);
break;
case NotifyCollectionChangedAction.Remove:
newArgs = new NotifyCollectionChangedEventArgs(e.Action, HeadersFromColumns(e.OldItems), e.OldStartingIndex);
break;
case NotifyCollectionChangedAction.Move:
newArgs = new NotifyCollectionChangedEventArgs(e.Action, HeadersFromColumns(e.OldItems), e.NewStartingIndex, e.OldStartingIndex);
break;
case NotifyCollectionChangedAction.Replace:
newArgs = new NotifyCollectionChangedEventArgs(e.Action, HeadersFromColumns(e.NewItems), HeadersFromColumns(e.OldItems), e.OldStartingIndex);
break;
default:
newArgs = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset);
break;
}
FireCollectionChanged(newArgs);
}
private void FireCollectionChanged(NotifyCollectionChangedEventArgs args)
{
if (CollectionChanged != null)
{
CollectionChanged(this, args);
}
}
private static object[] HeadersFromColumns(IList columns)
{
object[] headers = new object[columns.Count];
for (int i = 0; i < columns.Count; i++)
{
DataGridColumn column = columns[i] as DataGridColumn;
if (column != null)
{
headers[i] = column.Header;
}
else
{
headers[i] = null;
}
}
return headers;
}
#endregion
private ObservableCollection<DataGridColumn> _columns;
}
}