Imported Upstream version 5.0.0.42

Former-commit-id: fd56571888259555122d8a0f58c68838229cea2b
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2017-04-10 11:41:01 +00:00
parent 1190d13a04
commit 6bdd276d05
19939 changed files with 3099680 additions and 93811 deletions

View File

@ -0,0 +1,81 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.22609.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.ObjectModel.Tests", "tests\System.ObjectModel.Tests.csproj", "{82B54697-0251-47A1-8546-FC507D0F3B08}"
ProjectSection(ProjectDependencies) = postProject
{F24D3391-2928-4E83-AADE-A4461E5CAE50} = {F24D3391-2928-4E83-AADE-A4461E5CAE50}
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.ObjectModel", "src\System.ObjectModel.csproj", "{F24D3391-2928-4E83-AADE-A4461E5CAE50}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
DebugNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU = DebugNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU
ReleaseNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU = ReleaseNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU
DebugNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU = DebugNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU
ReleaseNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU = ReleaseNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU
DebugNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU = DebugNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU
ReleaseNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU = ReleaseNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU
DebugNETCoreAppnetcoreappnetcoreapp|AnyCPU = DebugNETCoreAppnetcoreappnetcoreapp|AnyCPU
ReleaseNETCoreAppnetcoreappnetcoreapp|AnyCPU = ReleaseNETCoreAppnetcoreappnetcoreapp|AnyCPU
DebugNETCoreAppnetcoreappnetcoreapp|AnyCPU = DebugNETCoreAppnetcoreappnetcoreapp|AnyCPU
ReleaseNETCoreAppnetcoreappnetcoreapp|AnyCPU = ReleaseNETCoreAppnetcoreappnetcoreapp|AnyCPU
DebugNETCoreAppnetcoreappnetcoreapp|AnyCPU = DebugNETCoreAppnetcoreappnetcoreapp|AnyCPU
ReleaseNETCoreAppnetcoreappnetcoreapp|AnyCPU = ReleaseNETCoreAppnetcoreappnetcoreapp|AnyCPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{82B54697-0251-47A1-8546-FC507D0F3B08}.DebugNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU.ActiveCfg = netcoreapp-Debug|Any CPU
{82B54697-0251-47A1-8546-FC507D0F3B08}.DebugNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU.Build.0 = netcoreapp-Debug|Any CPU
{82B54697-0251-47A1-8546-FC507D0F3B08}.ReleaseNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU.ActiveCfg = netcoreapp-Release|Any CPU
{82B54697-0251-47A1-8546-FC507D0F3B08}.ReleaseNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU.Build.0 = netcoreapp-Release|Any CPU
{82B54697-0251-47A1-8546-FC507D0F3B08}.DebugNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU.ActiveCfg = netcoreapp-Debug|Any CPU
{82B54697-0251-47A1-8546-FC507D0F3B08}.DebugNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU.Build.0 = netcoreapp-Debug|Any CPU
{82B54697-0251-47A1-8546-FC507D0F3B08}.ReleaseNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU.ActiveCfg = netcoreapp-Release|Any CPU
{82B54697-0251-47A1-8546-FC507D0F3B08}.ReleaseNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU.Build.0 = netcoreapp-Release|Any CPU
{82B54697-0251-47A1-8546-FC507D0F3B08}.DebugNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU.ActiveCfg = netcoreapp-Debug|Any CPU
{82B54697-0251-47A1-8546-FC507D0F3B08}.DebugNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU.Build.0 = netcoreapp-Debug|Any CPU
{82B54697-0251-47A1-8546-FC507D0F3B08}.ReleaseNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU.ActiveCfg = netcoreapp-Release|Any CPU
{82B54697-0251-47A1-8546-FC507D0F3B08}.ReleaseNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU.Build.0 = netcoreapp-Release|Any CPU
{82B54697-0251-47A1-8546-FC507D0F3B08}.DebugNETCoreAppnetcoreappnetcoreapp|AnyCPU.ActiveCfg = netcoreapp-Debug|Any CPU
{82B54697-0251-47A1-8546-FC507D0F3B08}.DebugNETCoreAppnetcoreappnetcoreapp|AnyCPU.Build.0 = netcoreapp-Debug|Any CPU
{82B54697-0251-47A1-8546-FC507D0F3B08}.ReleaseNETCoreAppnetcoreappnetcoreapp|AnyCPU.ActiveCfg = netcoreapp-Release|Any CPU
{82B54697-0251-47A1-8546-FC507D0F3B08}.ReleaseNETCoreAppnetcoreappnetcoreapp|AnyCPU.Build.0 = netcoreapp-Release|Any CPU
{82B54697-0251-47A1-8546-FC507D0F3B08}.DebugNETCoreAppnetcoreappnetcoreapp|AnyCPU.ActiveCfg = netcoreapp-Debug|Any CPU
{82B54697-0251-47A1-8546-FC507D0F3B08}.DebugNETCoreAppnetcoreappnetcoreapp|AnyCPU.Build.0 = netcoreapp-Debug|Any CPU
{82B54697-0251-47A1-8546-FC507D0F3B08}.ReleaseNETCoreAppnetcoreappnetcoreapp|AnyCPU.ActiveCfg = netcoreapp-Release|Any CPU
{82B54697-0251-47A1-8546-FC507D0F3B08}.ReleaseNETCoreAppnetcoreappnetcoreapp|AnyCPU.Build.0 = netcoreapp-Release|Any CPU
{82B54697-0251-47A1-8546-FC507D0F3B08}.DebugNETCoreAppnetcoreappnetcoreapp|AnyCPU.ActiveCfg = netcoreapp-Debug|Any CPU
{82B54697-0251-47A1-8546-FC507D0F3B08}.DebugNETCoreAppnetcoreappnetcoreapp|AnyCPU.Build.0 = netcoreapp-Debug|Any CPU
{82B54697-0251-47A1-8546-FC507D0F3B08}.ReleaseNETCoreAppnetcoreappnetcoreapp|AnyCPU.ActiveCfg = netcoreapp-Release|Any CPU
{82B54697-0251-47A1-8546-FC507D0F3B08}.ReleaseNETCoreAppnetcoreappnetcoreapp|AnyCPU.Build.0 = netcoreapp-Release|Any CPU
{F24D3391-2928-4E83-AADE-A4461E5CAE50}.DebugNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU.ActiveCfg = net463-Windows_NT-Debug|Any CPU
{F24D3391-2928-4E83-AADE-A4461E5CAE50}.DebugNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU.Build.0 = net463-Windows_NT-Debug|Any CPU
{F24D3391-2928-4E83-AADE-A4461E5CAE50}.ReleaseNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU.ActiveCfg = net463-Windows_NT-Release|Any CPU
{F24D3391-2928-4E83-AADE-A4461E5CAE50}.ReleaseNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU.Build.0 = net463-Windows_NT-Release|Any CPU
{F24D3391-2928-4E83-AADE-A4461E5CAE50}.DebugNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU.ActiveCfg = net463-Windows_NT-Debug|Any CPU
{F24D3391-2928-4E83-AADE-A4461E5CAE50}.DebugNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU.Build.0 = net463-Windows_NT-Debug|Any CPU
{F24D3391-2928-4E83-AADE-A4461E5CAE50}.ReleaseNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU.ActiveCfg = net463-Windows_NT-Release|Any CPU
{F24D3391-2928-4E83-AADE-A4461E5CAE50}.ReleaseNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU.Build.0 = net463-Windows_NT-Release|Any CPU
{F24D3391-2928-4E83-AADE-A4461E5CAE50}.DebugNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU.ActiveCfg = net463-Windows_NT-Debug|Any CPU
{F24D3391-2928-4E83-AADE-A4461E5CAE50}.DebugNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU.Build.0 = net463-Windows_NT-Debug|Any CPU
{F24D3391-2928-4E83-AADE-A4461E5CAE50}.ReleaseNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU.ActiveCfg = net463-Windows_NT-Release|Any CPU
{F24D3391-2928-4E83-AADE-A4461E5CAE50}.ReleaseNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU.Build.0 = net463-Windows_NT-Release|Any CPU
{F24D3391-2928-4E83-AADE-A4461E5CAE50}.DebugNETCoreAppnetcoreappnetcoreapp|AnyCPU.ActiveCfg = netcoreapp-Debug|Any CPU
{F24D3391-2928-4E83-AADE-A4461E5CAE50}.DebugNETCoreAppnetcoreappnetcoreapp|AnyCPU.Build.0 = netcoreapp-Debug|Any CPU
{F24D3391-2928-4E83-AADE-A4461E5CAE50}.ReleaseNETCoreAppnetcoreappnetcoreapp|AnyCPU.ActiveCfg = netcoreapp-Release|Any CPU
{F24D3391-2928-4E83-AADE-A4461E5CAE50}.ReleaseNETCoreAppnetcoreappnetcoreapp|AnyCPU.Build.0 = netcoreapp-Release|Any CPU
{F24D3391-2928-4E83-AADE-A4461E5CAE50}.DebugNETCoreAppnetcoreappnetcoreapp|AnyCPU.ActiveCfg = netcoreapp-Debug|Any CPU
{F24D3391-2928-4E83-AADE-A4461E5CAE50}.DebugNETCoreAppnetcoreappnetcoreapp|AnyCPU.Build.0 = netcoreapp-Debug|Any CPU
{F24D3391-2928-4E83-AADE-A4461E5CAE50}.ReleaseNETCoreAppnetcoreappnetcoreapp|AnyCPU.ActiveCfg = netcoreapp-Release|Any CPU
{F24D3391-2928-4E83-AADE-A4461E5CAE50}.ReleaseNETCoreAppnetcoreappnetcoreapp|AnyCPU.Build.0 = netcoreapp-Release|Any CPU
{F24D3391-2928-4E83-AADE-A4461E5CAE50}.DebugNETCoreAppnetcoreappnetcoreapp|AnyCPU.ActiveCfg = netcoreapp-Debug|Any CPU
{F24D3391-2928-4E83-AADE-A4461E5CAE50}.DebugNETCoreAppnetcoreappnetcoreapp|AnyCPU.Build.0 = netcoreapp-Debug|Any CPU
{F24D3391-2928-4E83-AADE-A4461E5CAE50}.ReleaseNETCoreAppnetcoreappnetcoreapp|AnyCPU.ActiveCfg = netcoreapp-Release|Any CPU
{F24D3391-2928-4E83-AADE-A4461E5CAE50}.ReleaseNETCoreAppnetcoreappnetcoreapp|AnyCPU.Build.0 = netcoreapp-Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\dir.props" />
<PropertyGroup>
<AssemblyVersion>4.1.0.0</AssemblyVersion>
<IsNETCoreApp>true</IsNETCoreApp>
</PropertyGroup>
</Project>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<BuildConfigurations>
netcoreapp;
uap;
</BuildConfigurations>
</PropertyGroup>
</Project>

View File

@ -0,0 +1,207 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// ------------------------------------------------------------------------------
// Changes to this file must follow the http://aka.ms/api-review process.
// ------------------------------------------------------------------------------
namespace System.Collections.ObjectModel
{
public abstract partial class KeyedCollection<TKey, TItem> : System.Collections.ObjectModel.Collection<TItem>
{
protected KeyedCollection() { }
protected KeyedCollection(System.Collections.Generic.IEqualityComparer<TKey> comparer) { }
protected KeyedCollection(System.Collections.Generic.IEqualityComparer<TKey> comparer, int dictionaryCreationThreshold) { }
public System.Collections.Generic.IEqualityComparer<TKey> Comparer { get { throw null; } }
protected System.Collections.Generic.IDictionary<TKey, TItem> Dictionary { get { throw null; } }
public TItem this[TKey key] { get { throw null; } }
protected void ChangeItemKey(TItem item, TKey newKey) { }
protected override void ClearItems() { }
public bool Contains(TKey key) { throw null; }
public bool TryGetValue(TKey key, out TItem item) { throw null; }
protected abstract TKey GetKeyForItem(TItem item);
protected override void InsertItem(int index, TItem item) { }
public bool Remove(TKey key) { throw null; }
protected override void RemoveItem(int index) { }
protected override void SetItem(int index, TItem item) { }
}
public partial class ObservableCollection<T> : System.Collections.ObjectModel.Collection<T>, System.Collections.Specialized.INotifyCollectionChanged, System.ComponentModel.INotifyPropertyChanged
{
public ObservableCollection() { }
public ObservableCollection(System.Collections.Generic.List<T> list) { }
public ObservableCollection(System.Collections.Generic.IEnumerable<T> collection) { }
public virtual event System.Collections.Specialized.NotifyCollectionChangedEventHandler CollectionChanged { add { } remove { } }
protected virtual event System.ComponentModel.PropertyChangedEventHandler PropertyChanged { add { } remove { } }
event System.ComponentModel.PropertyChangedEventHandler System.ComponentModel.INotifyPropertyChanged.PropertyChanged { add { } remove { } }
protected System.IDisposable BlockReentrancy() { throw null; }
protected void CheckReentrancy() { }
protected override void ClearItems() { }
protected override void InsertItem(int index, T item) { }
public void Move(int oldIndex, int newIndex) { }
protected virtual void MoveItem(int oldIndex, int newIndex) { }
protected virtual void OnCollectionChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e) { }
protected virtual void OnPropertyChanged(System.ComponentModel.PropertyChangedEventArgs e) { }
protected override void RemoveItem(int index) { }
protected override void SetItem(int index, T item) { }
}
public partial class ReadOnlyDictionary<TKey, TValue> : System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<TKey, TValue>>, System.Collections.Generic.IDictionary<TKey, TValue>, System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<TKey, TValue>>, System.Collections.Generic.IReadOnlyCollection<System.Collections.Generic.KeyValuePair<TKey, TValue>>, System.Collections.Generic.IReadOnlyDictionary<TKey, TValue>, System.Collections.ICollection, System.Collections.IDictionary, System.Collections.IEnumerable
{
public ReadOnlyDictionary(System.Collections.Generic.IDictionary<TKey, TValue> dictionary) { }
public int Count { get { throw null; } }
protected System.Collections.Generic.IDictionary<TKey, TValue> Dictionary { get { throw null; } }
public TValue this[TKey key] { get { throw null; } }
public System.Collections.ObjectModel.ReadOnlyDictionary<TKey, TValue>.KeyCollection Keys { get { throw null; } }
bool System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<TKey, TValue>>.IsReadOnly { get { throw null; } }
TValue System.Collections.Generic.IDictionary<TKey, TValue>.this[TKey key] { get { throw null; } set { } }
System.Collections.Generic.ICollection<TKey> System.Collections.Generic.IDictionary<TKey, TValue>.Keys { get { throw null; } }
System.Collections.Generic.ICollection<TValue> System.Collections.Generic.IDictionary<TKey, TValue>.Values { get { throw null; } }
System.Collections.Generic.IEnumerable<TKey> System.Collections.Generic.IReadOnlyDictionary<TKey, TValue>.Keys { get { throw null; } }
System.Collections.Generic.IEnumerable<TValue> System.Collections.Generic.IReadOnlyDictionary<TKey, TValue>.Values { get { throw null; } }
bool System.Collections.ICollection.IsSynchronized { get { throw null; } }
object System.Collections.ICollection.SyncRoot { get { throw null; } }
bool System.Collections.IDictionary.IsFixedSize { get { throw null; } }
bool System.Collections.IDictionary.IsReadOnly { get { throw null; } }
object System.Collections.IDictionary.this[object key] { get { throw null; } set { } }
System.Collections.ICollection System.Collections.IDictionary.Keys { get { throw null; } }
System.Collections.ICollection System.Collections.IDictionary.Values { get { throw null; } }
public System.Collections.ObjectModel.ReadOnlyDictionary<TKey, TValue>.ValueCollection Values { get { throw null; } }
public bool ContainsKey(TKey key) { throw null; }
public System.Collections.Generic.IEnumerator<System.Collections.Generic.KeyValuePair<TKey, TValue>> GetEnumerator() { throw null; }
void System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<TKey, TValue>>.Add(System.Collections.Generic.KeyValuePair<TKey, TValue> item) { }
void System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<TKey, TValue>>.Clear() { }
bool System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<TKey, TValue>>.Contains(System.Collections.Generic.KeyValuePair<TKey, TValue> item) { throw null; }
void System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<TKey, TValue>>.CopyTo(System.Collections.Generic.KeyValuePair<TKey, TValue>[] array, int arrayIndex) { }
bool System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<TKey, TValue>>.Remove(System.Collections.Generic.KeyValuePair<TKey, TValue> item) { throw null; }
void System.Collections.Generic.IDictionary<TKey, TValue>.Add(TKey key, TValue value) { }
bool System.Collections.Generic.IDictionary<TKey, TValue>.Remove(TKey key) { throw null; }
void System.Collections.ICollection.CopyTo(System.Array array, int index) { }
void System.Collections.IDictionary.Add(object key, object value) { }
void System.Collections.IDictionary.Clear() { }
bool System.Collections.IDictionary.Contains(object key) { throw null; }
System.Collections.IDictionaryEnumerator System.Collections.IDictionary.GetEnumerator() { throw null; }
void System.Collections.IDictionary.Remove(object key) { }
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; }
public bool TryGetValue(TKey key, out TValue value) { throw null; }
public sealed partial class KeyCollection : System.Collections.Generic.ICollection<TKey>, System.Collections.Generic.IEnumerable<TKey>, System.Collections.Generic.IReadOnlyCollection<TKey>, System.Collections.ICollection, System.Collections.IEnumerable
{
internal KeyCollection() { }
public int Count { get { throw null; } }
bool System.Collections.Generic.ICollection<TKey>.IsReadOnly { get { throw null; } }
bool System.Collections.ICollection.IsSynchronized { get { throw null; } }
object System.Collections.ICollection.SyncRoot { get { throw null; } }
public void CopyTo(TKey[] array, int arrayIndex) { }
public System.Collections.Generic.IEnumerator<TKey> GetEnumerator() { throw null; }
void System.Collections.Generic.ICollection<TKey>.Add(TKey item) { }
void System.Collections.Generic.ICollection<TKey>.Clear() { }
bool System.Collections.Generic.ICollection<TKey>.Contains(TKey item) { throw null; }
bool System.Collections.Generic.ICollection<TKey>.Remove(TKey item) { throw null; }
void System.Collections.ICollection.CopyTo(System.Array array, int index) { }
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; }
}
public sealed partial class ValueCollection : System.Collections.Generic.ICollection<TValue>, System.Collections.Generic.IEnumerable<TValue>, System.Collections.Generic.IReadOnlyCollection<TValue>, System.Collections.ICollection, System.Collections.IEnumerable
{
internal ValueCollection() { }
public int Count { get { throw null; } }
bool System.Collections.Generic.ICollection<TValue>.IsReadOnly { get { throw null; } }
bool System.Collections.ICollection.IsSynchronized { get { throw null; } }
object System.Collections.ICollection.SyncRoot { get { throw null; } }
public void CopyTo(TValue[] array, int arrayIndex) { }
public System.Collections.Generic.IEnumerator<TValue> GetEnumerator() { throw null; }
void System.Collections.Generic.ICollection<TValue>.Add(TValue item) { }
void System.Collections.Generic.ICollection<TValue>.Clear() { }
bool System.Collections.Generic.ICollection<TValue>.Contains(TValue item) { throw null; }
bool System.Collections.Generic.ICollection<TValue>.Remove(TValue item) { throw null; }
void System.Collections.ICollection.CopyTo(System.Array array, int index) { }
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; }
}
}
public partial class ReadOnlyObservableCollection<T> : System.Collections.ObjectModel.ReadOnlyCollection<T>, System.Collections.Specialized.INotifyCollectionChanged, System.ComponentModel.INotifyPropertyChanged
{
public ReadOnlyObservableCollection(System.Collections.ObjectModel.ObservableCollection<T> list) : base(default(System.Collections.Generic.IList<T>)) { }
protected virtual event System.Collections.Specialized.NotifyCollectionChangedEventHandler CollectionChanged { add { } remove { } }
protected virtual event System.ComponentModel.PropertyChangedEventHandler PropertyChanged { add { } remove { } }
event System.Collections.Specialized.NotifyCollectionChangedEventHandler System.Collections.Specialized.INotifyCollectionChanged.CollectionChanged { add { } remove { } }
event System.ComponentModel.PropertyChangedEventHandler System.ComponentModel.INotifyPropertyChanged.PropertyChanged { add { } remove { } }
protected virtual void OnCollectionChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs args) { }
protected virtual void OnPropertyChanged(System.ComponentModel.PropertyChangedEventArgs args) { }
}
}
namespace System.Collections.Specialized
{
public partial interface INotifyCollectionChanged
{
event System.Collections.Specialized.NotifyCollectionChangedEventHandler CollectionChanged;
}
public enum NotifyCollectionChangedAction
{
Add = 0,
Move = 3,
Remove = 1,
Replace = 2,
Reset = 4,
}
public partial class NotifyCollectionChangedEventArgs : System.EventArgs
{
public NotifyCollectionChangedEventArgs(System.Collections.Specialized.NotifyCollectionChangedAction action) { }
public NotifyCollectionChangedEventArgs(System.Collections.Specialized.NotifyCollectionChangedAction action, System.Collections.IList changedItems) { }
public NotifyCollectionChangedEventArgs(System.Collections.Specialized.NotifyCollectionChangedAction action, System.Collections.IList newItems, System.Collections.IList oldItems) { }
public NotifyCollectionChangedEventArgs(System.Collections.Specialized.NotifyCollectionChangedAction action, System.Collections.IList newItems, System.Collections.IList oldItems, int startingIndex) { }
public NotifyCollectionChangedEventArgs(System.Collections.Specialized.NotifyCollectionChangedAction action, System.Collections.IList changedItems, int startingIndex) { }
public NotifyCollectionChangedEventArgs(System.Collections.Specialized.NotifyCollectionChangedAction action, System.Collections.IList changedItems, int index, int oldIndex) { }
public NotifyCollectionChangedEventArgs(System.Collections.Specialized.NotifyCollectionChangedAction action, object changedItem) { }
public NotifyCollectionChangedEventArgs(System.Collections.Specialized.NotifyCollectionChangedAction action, object changedItem, int index) { }
public NotifyCollectionChangedEventArgs(System.Collections.Specialized.NotifyCollectionChangedAction action, object changedItem, int index, int oldIndex) { }
public NotifyCollectionChangedEventArgs(System.Collections.Specialized.NotifyCollectionChangedAction action, object newItem, object oldItem) { }
public NotifyCollectionChangedEventArgs(System.Collections.Specialized.NotifyCollectionChangedAction action, object newItem, object oldItem, int index) { }
public System.Collections.Specialized.NotifyCollectionChangedAction Action { get { throw null; } }
public System.Collections.IList NewItems { get { throw null; } }
public int NewStartingIndex { get { throw null; } }
public System.Collections.IList OldItems { get { throw null; } }
public int OldStartingIndex { get { throw null; } }
}
public delegate void NotifyCollectionChangedEventHandler(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e);
}
namespace System.ComponentModel
{
public partial class DataErrorsChangedEventArgs : System.EventArgs
{
public DataErrorsChangedEventArgs(string propertyName) { }
public virtual string PropertyName { get { throw null; } }
}
public partial interface INotifyDataErrorInfo
{
bool HasErrors { get; }
event System.EventHandler<System.ComponentModel.DataErrorsChangedEventArgs> ErrorsChanged;
System.Collections.IEnumerable GetErrors(string propertyName);
}
public partial interface INotifyPropertyChanged
{
event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
}
public partial interface INotifyPropertyChanging
{
event System.ComponentModel.PropertyChangingEventHandler PropertyChanging;
}
public partial class PropertyChangedEventArgs : System.EventArgs
{
public PropertyChangedEventArgs(string propertyName) { }
public virtual string PropertyName { get { throw null; } }
}
public delegate void PropertyChangedEventHandler(object sender, System.ComponentModel.PropertyChangedEventArgs e);
public partial class PropertyChangingEventArgs : System.EventArgs
{
public PropertyChangingEventArgs(string propertyName) { }
public virtual string PropertyName { get { throw null; } }
}
public delegate void PropertyChangingEventHandler(object sender, System.ComponentModel.PropertyChangingEventArgs e);
}
namespace System.Windows.Input
{
public partial interface ICommand
{
event System.EventHandler CanExecuteChanged;
bool CanExecute(object parameter);
void Execute(object parameter);
}
}

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcoreapp-Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcoreapp-Release|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'uap-Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'uap-Release|AnyCPU'" />
<ItemGroup>
<Compile Include="System.ObjectModel.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\System.Runtime\ref\System.Runtime.csproj" />
<ProjectReference Include="..\..\System.Collections\ref\System.Collections.csproj" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
</Project>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<BuildConfigurations>
net463-Windows_NT;
netcoreapp;
</BuildConfigurations>
</PropertyGroup>
</Project>

View File

@ -0,0 +1,165 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="ArgumentOutOfRange_InvalidThreshold" xml:space="preserve">
<value>The specified threshold for creating dictionary is out of range.</value>
</data>
<data name="Argument_ItemNotExist" xml:space="preserve">
<value>The specified item does not exist in this KeyedCollection.</value>
</data>
<data name="Argument_AddingDuplicate" xml:space="preserve">
<value>An item with the same key has already been added. Key: {0}</value>
</data>
<data name="Arg_NonZeroLowerBound" xml:space="preserve">
<value>The lower bound of target array must be zero.</value>
</data>
<data name="Arg_ArrayPlusOffTooSmall" xml:space="preserve">
<value>Destination array is not long enough to copy all the items in the collection. Check array index and length.</value>
</data>
<data name="ArgumentOutOfRange_NeedNonNegNum" xml:space="preserve">
<value>Non-negative number required.</value>
</data>
<data name="IndexCannotBeNegative" xml:space="preserve">
<value>Index cannot be negative.</value>
</data>
<data name="NotSupported_ReadOnlyCollection" xml:space="preserve">
<value>Collection is read-only.</value>
</data>
<data name="ObservableCollectionReentrancyNotAllowed" xml:space="preserve">
<value>Cannot change ObservableCollection during a CollectionChanged event.</value>
</data>
<data name="WrongActionForCtor" xml:space="preserve">
<value>Constructor supports only the '{0}' action.</value>
</data>
<data name="MustBeResetAddOrRemoveActionForCtor" xml:space="preserve">
<value>Constructor only supports either a Reset, Add, or Remove action.</value>
</data>
<data name="ResetActionRequiresNullItem" xml:space="preserve">
<value>Reset action must be initialized with no changed items.</value>
</data>
<data name="ResetActionRequiresIndexMinus1" xml:space="preserve">
<value>Reset action must be initialized with index -1.</value>
</data>
<data name="Arg_RankMultiDimNotSupported" xml:space="preserve">
<value>Only single dimensional arrays are supported for the requested action.</value>
</data>
<data name="Argument_InvalidArrayType" xml:space="preserve">
<value>Target array type is not compatible with the type of items in the collection.</value>
</data>
</root>

View File

@ -0,0 +1,53 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
<PropertyGroup>
<ProjectGuid>{F24D3391-2928-4E83-AADE-A4461E5CAE50}</ProjectGuid>
<AssemblyName>System.ObjectModel</AssemblyName>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<IsPartialFacadeAssembly Condition="'$(TargetGroup)' == 'net463'">true</IsPartialFacadeAssembly>
<ResourcesSourceOutputDirectory Condition="'$(TargetGroup)' == 'net463'">None</ResourcesSourceOutputDirectory>
</PropertyGroup>
<ItemGroup Condition="'$(TargetGroup)' == 'net463'">
<ContractProject Include="..\ref\System.ObjectModel.csproj">
<TargetGroup>netcoreapp</TargetGroup>
</ContractProject>
</ItemGroup>
<!-- Default configurations to help VS understand the configurations -->
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='net463-Windows_NT-Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='net463-Windows_NT-Release|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='netcoreapp-Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='netcoreapp-Release|AnyCPU'" />
<ItemGroup Condition="'$(TargetGroup)' == 'netcoreapp'">
<Compile Include="System\Collections\Generic\DebugView.cs" />
<Compile Include="System\Collections\Specialized\INotifyCollectionChanged.cs" />
<Compile Include="System\Collections\Specialized\NotifyCollectionChangedEventArgs.cs" />
<Compile Include="System\Collections\ObjectModel\KeyedCollection.cs" />
<Compile Include="System\Collections\ObjectModel\ObservableCollection.cs" />
<Compile Include="System\Collections\ObjectModel\ReadOnlyDictionary.cs" />
<Compile Include="System\Collections\ObjectModel\ReadOnlyObservableCollection.cs" />
<Compile Include="System\ComponentModel\DataErrorsChangedEventArgs.cs" />
<Compile Include="System\ComponentModel\INotifyDataErrorInfo.cs" />
<Compile Include="System\ComponentModel\INotifyPropertyChanged.cs" />
<Compile Include="System\ComponentModel\INotifyPropertyChanging.cs" />
<Compile Include="System\ComponentModel\PropertyChangedEventArgs.cs" />
<Compile Include="System\ComponentModel\PropertyChangedEventHandler.cs" />
<Compile Include="System\ComponentModel\PropertyChangingEventArgs.cs" />
<Compile Include="System\ComponentModel\PropertyChangingEventHandler.cs" />
<Compile Include="System\Windows\Input\ICommand.cs" />
</ItemGroup>
<ItemGroup Condition="'$(TargetGroup)' == 'net463'">
<TargetingPackReference Include="mscorlib" />
<TargetingPackReference Include="System" />
</ItemGroup>
<ItemGroup>
<Reference Include="System.Collections" />
<Reference Include="System.Diagnostics.Contracts" />
<Reference Include="System.Diagnostics.Debug" />
<Reference Include="System.Diagnostics.Tools" />
<Reference Include="System.Resources.ResourceManager" />
<Reference Include="System.Runtime" />
<Reference Include="System.Threading" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
</Project>

View File

@ -0,0 +1,58 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Diagnostics;
namespace System.Collections.Generic
{
internal sealed class CollectionDebugView<T>
{
private readonly ICollection<T> _collection;
public CollectionDebugView(ICollection<T> collection)
{
if (collection == null)
throw new ArgumentNullException(nameof(collection));
_collection = collection;
}
[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
public T[] Items
{
get
{
T[] items = new T[_collection.Count];
_collection.CopyTo(items, 0);
return items;
}
}
}
internal sealed class DictionaryDebugView<K, V>
{
private readonly IDictionary<K, V> _dict;
public DictionaryDebugView(IDictionary<K, V> dictionary)
{
if (dictionary == null)
throw new ArgumentNullException(nameof(dictionary));
_dict = dictionary;
}
[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
public KeyValuePair<K, V>[] Items
{
get
{
KeyValuePair<K, V>[] items = new KeyValuePair<K, V>[_dict.Count];
_dict.CopyTo(items, 0);
return items;
}
}
}
}

View File

@ -0,0 +1,308 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Diagnostics;
namespace System.Collections.ObjectModel
{
[Serializable]
[DebuggerTypeProxy(typeof(CollectionDebugView<>))]
[DebuggerDisplay("Count = {Count}")]
public abstract class KeyedCollection<TKey, TItem> : Collection<TItem>
{
private const int defaultThreshold = 0;
private readonly IEqualityComparer<TKey> _comparer;
private Dictionary<TKey, TItem> _dict;
private int _keyCount;
private readonly int _threshold;
protected KeyedCollection() : this(null, defaultThreshold) { }
protected KeyedCollection(IEqualityComparer<TKey> comparer) : this(comparer, defaultThreshold) { }
protected KeyedCollection(IEqualityComparer<TKey> comparer, int dictionaryCreationThreshold)
: base(new List<TItem>()) // Be explicit about the use of List<T> so we can foreach over
// Items internally without enumerator allocations.
{
if (comparer == null)
{
comparer = EqualityComparer<TKey>.Default;
}
if (dictionaryCreationThreshold == -1)
{
dictionaryCreationThreshold = int.MaxValue;
}
if (dictionaryCreationThreshold < -1)
{
throw new ArgumentOutOfRangeException(nameof(dictionaryCreationThreshold), SR.ArgumentOutOfRange_InvalidThreshold);
}
_comparer = comparer;
_threshold = dictionaryCreationThreshold;
}
/// <summary>
/// Enables the use of foreach internally without allocations using <see cref="List{T}"/>'s struct enumerator.
/// </summary>
new private List<TItem> Items
{
get
{
Debug.Assert(base.Items is List<TItem>);
return (List<TItem>)base.Items;
}
}
public IEqualityComparer<TKey> Comparer
{
get
{
return _comparer;
}
}
public TItem this[TKey key]
{
get
{
TItem item;
if (TryGetValue(key, out item))
{
return item;
}
throw new KeyNotFoundException();
}
}
public bool Contains(TKey key)
{
if (key == null)
{
throw new ArgumentNullException(nameof(key));
}
if (_dict != null)
{
return _dict.ContainsKey(key);
}
foreach (TItem item in Items)
{
if (_comparer.Equals(GetKeyForItem(item), key)) return true;
}
return false;
}
public bool TryGetValue(TKey key, out TItem item)
{
if (key == null)
{
throw new ArgumentNullException(nameof(key));
}
if (_dict != null)
{
return _dict.TryGetValue(key, out item);
}
foreach (TItem itemInItems in Items)
{
TKey keyInItems = GetKeyForItem(itemInItems);
if (keyInItems != null && _comparer.Equals(key, keyInItems))
{
item = itemInItems;
return true;
}
}
item = default(TItem);
return false;
}
private bool ContainsItem(TItem item)
{
TKey key;
if ((_dict == null) || ((key = GetKeyForItem(item)) == null))
{
return Items.Contains(item);
}
TItem itemInDict;
bool exist = _dict.TryGetValue(key, out itemInDict);
if (exist)
{
return EqualityComparer<TItem>.Default.Equals(itemInDict, item);
}
return false;
}
public bool Remove(TKey key)
{
if (key == null)
{
throw new ArgumentNullException(nameof(key));
}
if (_dict != null)
{
TItem item;
return _dict.TryGetValue(key, out item) && Remove(item);
}
for (int i = 0; i < Items.Count; i++)
{
if (_comparer.Equals(GetKeyForItem(Items[i]), key))
{
RemoveItem(i);
return true;
}
}
return false;
}
protected IDictionary<TKey, TItem> Dictionary
{
get { return _dict; }
}
protected void ChangeItemKey(TItem item, TKey newKey)
{
// Check if the item exists in the collection
if (!ContainsItem(item))
{
throw new ArgumentException(SR.Argument_ItemNotExist);
}
TKey oldKey = GetKeyForItem(item);
if (!_comparer.Equals(oldKey, newKey))
{
if (newKey != null)
{
AddKey(newKey, item);
}
if (oldKey != null)
{
RemoveKey(oldKey);
}
}
}
protected override void ClearItems()
{
base.ClearItems();
if (_dict != null)
{
_dict.Clear();
}
_keyCount = 0;
}
protected abstract TKey GetKeyForItem(TItem item);
protected override void InsertItem(int index, TItem item)
{
TKey key = GetKeyForItem(item);
if (key != null)
{
AddKey(key, item);
}
base.InsertItem(index, item);
}
protected override void RemoveItem(int index)
{
TKey key = GetKeyForItem(Items[index]);
if (key != null)
{
RemoveKey(key);
}
base.RemoveItem(index);
}
protected override void SetItem(int index, TItem item)
{
TKey newKey = GetKeyForItem(item);
TKey oldKey = GetKeyForItem(Items[index]);
if (_comparer.Equals(oldKey, newKey))
{
if (newKey != null && _dict != null)
{
_dict[newKey] = item;
}
}
else
{
if (newKey != null)
{
AddKey(newKey, item);
}
if (oldKey != null)
{
RemoveKey(oldKey);
}
}
base.SetItem(index, item);
}
private void AddKey(TKey key, TItem item)
{
if (_dict != null)
{
_dict.Add(key, item);
}
else if (_keyCount == _threshold)
{
CreateDictionary();
_dict.Add(key, item);
}
else
{
if (Contains(key))
{
throw new ArgumentException(SR.Format(SR.Argument_AddingDuplicate, key));
}
_keyCount++;
}
}
private void CreateDictionary()
{
_dict = new Dictionary<TKey, TItem>(_comparer);
foreach (TItem item in Items)
{
TKey key = GetKeyForItem(item);
if (key != null)
{
_dict.Add(key, item);
}
}
}
private void RemoveKey(TKey key)
{
Debug.Assert(key != null, "key shouldn't be null!");
if (_dict != null)
{
_dict.Remove(key);
}
else
{
_keyCount--;
}
}
}
}

View File

@ -0,0 +1,388 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Diagnostics;
namespace System.Collections.ObjectModel
{
/// <summary>
/// Implementation of a dynamic data collection based on generic Collection&lt;T&gt;,
/// implementing INotifyCollectionChanged to notify listeners
/// when items get added, removed or the whole list is refreshed.
/// </summary>
[Serializable]
[DebuggerTypeProxy(typeof(CollectionDebugView<>))]
[DebuggerDisplay("Count = {Count}")]
public class ObservableCollection<T> : Collection<T>, INotifyCollectionChanged, INotifyPropertyChanged
{
//------------------------------------------------------
//
// Constructors
//
//------------------------------------------------------
#region Constructors
/// <summary>
/// Initializes a new instance of ObservableCollection that is empty and has default initial capacity.
/// </summary>
public ObservableCollection() { }
/// <summary>
/// Initializes a new instance of the ObservableCollection class that contains
/// elements copied from the specified collection and has sufficient capacity
/// to accommodate the number of elements copied.
/// </summary>
/// <param name="collection">The collection whose elements are copied to the new list.</param>
/// <remarks>
/// The elements are copied onto the ObservableCollection in the
/// same order they are read by the enumerator of the collection.
/// </remarks>
/// <exception cref="ArgumentNullException"> collection is a null reference </exception>
public ObservableCollection(IEnumerable<T> collection) : base(CreateCopy(collection, nameof(collection))) { }
/// <summary>
/// Initializes a new instance of the ObservableCollection class
/// that contains elements copied from the specified list
/// </summary>
/// <param name="list">The list whose elements are copied to the new list.</param>
/// <remarks>
/// The elements are copied onto the ObservableCollection in the
/// same order they are read by the enumerator of the list.
/// </remarks>
/// <exception cref="ArgumentNullException"> list is a null reference </exception>
public ObservableCollection(List<T> list) : base(CreateCopy(list, nameof(list))) { }
private static List<T> CreateCopy(IEnumerable<T> collection, string paramName)
{
if (collection == null)
throw new ArgumentNullException(paramName);
return new List<T>(collection);
}
#endregion Constructors
//------------------------------------------------------
//
// Public Methods
//
//------------------------------------------------------
#region Public Methods
/// <summary>
/// Move item at oldIndex to newIndex.
/// </summary>
public void Move(int oldIndex, int newIndex)
{
MoveItem(oldIndex, newIndex);
}
#endregion Public Methods
//------------------------------------------------------
//
// Public Events
//
//------------------------------------------------------
#region Public Events
//------------------------------------------------------
#region INotifyPropertyChanged implementation
/// <summary>
/// PropertyChanged event (per <see cref="INotifyPropertyChanged" />).
/// </summary>
event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged
{
add
{
PropertyChanged += value;
}
remove
{
PropertyChanged -= value;
}
}
#endregion INotifyPropertyChanged implementation
//------------------------------------------------------
/// <summary>
/// Occurs when the collection changes, either by adding or removing an item.
/// </summary>
/// <remarks>
/// see <seealso cref="INotifyCollectionChanged"/>
/// </remarks>
[field: NonSerialized]
public virtual event NotifyCollectionChangedEventHandler CollectionChanged;
#endregion Public Events
//------------------------------------------------------
//
// Protected Methods
//
//------------------------------------------------------
#region Protected Methods
/// <summary>
/// Called by base class Collection&lt;T&gt; when the list is being cleared;
/// raises a CollectionChanged event to any listeners.
/// </summary>
protected override void ClearItems()
{
CheckReentrancy();
base.ClearItems();
OnCountPropertyChanged();
OnIndexerPropertyChanged();
OnCollectionReset();
}
/// <summary>
/// Called by base class Collection&lt;T&gt; when an item is removed from list;
/// raises a CollectionChanged event to any listeners.
/// </summary>
protected override void RemoveItem(int index)
{
CheckReentrancy();
T removedItem = this[index];
base.RemoveItem(index);
OnCountPropertyChanged();
OnIndexerPropertyChanged();
OnCollectionChanged(NotifyCollectionChangedAction.Remove, removedItem, index);
}
/// <summary>
/// Called by base class Collection&lt;T&gt; when an item is added to list;
/// raises a CollectionChanged event to any listeners.
/// </summary>
protected override void InsertItem(int index, T item)
{
CheckReentrancy();
base.InsertItem(index, item);
OnCountPropertyChanged();
OnIndexerPropertyChanged();
OnCollectionChanged(NotifyCollectionChangedAction.Add, item, index);
}
/// <summary>
/// Called by base class Collection&lt;T&gt; when an item is set in list;
/// raises a CollectionChanged event to any listeners.
/// </summary>
protected override void SetItem(int index, T item)
{
CheckReentrancy();
T originalItem = this[index];
base.SetItem(index, item);
OnIndexerPropertyChanged();
OnCollectionChanged(NotifyCollectionChangedAction.Replace, originalItem, item, index);
}
/// <summary>
/// Called by base class ObservableCollection&lt;T&gt; when an item is to be moved within the list;
/// raises a CollectionChanged event to any listeners.
/// </summary>
protected virtual void MoveItem(int oldIndex, int newIndex)
{
CheckReentrancy();
T removedItem = this[oldIndex];
base.RemoveItem(oldIndex);
base.InsertItem(newIndex, removedItem);
OnIndexerPropertyChanged();
OnCollectionChanged(NotifyCollectionChangedAction.Move, removedItem, newIndex, oldIndex);
}
/// <summary>
/// Raises a PropertyChanged event (per <see cref="INotifyPropertyChanged" />).
/// </summary>
protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
{
PropertyChanged?.Invoke(this, e);
}
/// <summary>
/// PropertyChanged event (per <see cref="INotifyPropertyChanged" />).
/// </summary>
[field: NonSerialized]
protected virtual event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Raise CollectionChanged event to any listeners.
/// Properties/methods modifying this ObservableCollection will raise
/// a collection changed event through this virtual method.
/// </summary>
/// <remarks>
/// When overriding this method, either call its base implementation
/// or call <see cref="BlockReentrancy"/> to guard against reentrant collection changes.
/// </remarks>
protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
NotifyCollectionChangedEventHandler handler = CollectionChanged;
if (handler != null)
{
// Not calling BlockReentrancy() here to avoid the IDisposable box allocation.
_blockReentrancyCount++;
using (new BlockReentrancyDisposable(this))
{
handler(this, e);
}
}
}
/// <summary>
/// Disallow reentrant attempts to change this collection. E.g. a event handler
/// of the CollectionChanged event is not allowed to make changes to this collection.
/// </summary>
/// <remarks>
/// typical usage is to wrap e.g. a OnCollectionChanged call with a using() scope:
/// <code>
/// using (BlockReentrancy())
/// {
/// CollectionChanged(this, new NotifyCollectionChangedEventArgs(action, item, index));
/// }
/// </code>
/// </remarks>
protected IDisposable BlockReentrancy()
{
_blockReentrancyCount++;
// Lazily box the struct as IDisposable once and reuse the same boxed instance with subsequent calls.
return _boxedBlockReentrancyDisposable ?? (_boxedBlockReentrancyDisposable = new BlockReentrancyDisposable(this));
}
/// <summary> Check and assert for reentrant attempts to change this collection. </summary>
/// <exception cref="InvalidOperationException"> raised when changing the collection
/// while another collection change is still being notified to other listeners </exception>
protected void CheckReentrancy()
{
if (_blockReentrancyCount > 0)
{
// we can allow changes if there's only one listener - the problem
// only arises if reentrant changes make the original event args
// invalid for later listeners. This keeps existing code working
// (e.g. Selector.SelectedItems).
if (CollectionChanged?.GetInvocationList().Length > 1)
throw new InvalidOperationException(SR.ObservableCollectionReentrancyNotAllowed);
}
}
#endregion Protected Methods
//------------------------------------------------------
//
// Private Methods
//
//------------------------------------------------------
#region Private Methods
/// <summary>
/// Helper to raise a PropertyChanged event for the Count property
/// </summary>
private void OnCountPropertyChanged()
{
OnPropertyChanged(EventArgsCache.CountPropertyChanged);
}
/// <summary>
/// Helper to raise a PropertyChanged event for the Indexer property
/// </summary>
private void OnIndexerPropertyChanged()
{
OnPropertyChanged(EventArgsCache.IndexerPropertyChanged);
}
/// <summary>
/// Helper to raise CollectionChanged event to any listeners
/// </summary>
private void OnCollectionChanged(NotifyCollectionChangedAction action, object item, int index)
{
OnCollectionChanged(new NotifyCollectionChangedEventArgs(action, item, index));
}
/// <summary>
/// Helper to raise CollectionChanged event to any listeners
/// </summary>
private void OnCollectionChanged(NotifyCollectionChangedAction action, object item, int index, int oldIndex)
{
OnCollectionChanged(new NotifyCollectionChangedEventArgs(action, item, index, oldIndex));
}
/// <summary>
/// Helper to raise CollectionChanged event to any listeners
/// </summary>
private void OnCollectionChanged(NotifyCollectionChangedAction action, object oldItem, object newItem, int index)
{
OnCollectionChanged(new NotifyCollectionChangedEventArgs(action, newItem, oldItem, index));
}
/// <summary>
/// Helper to raise CollectionChanged event with action == Reset to any listeners
/// </summary>
private void OnCollectionReset()
{
OnCollectionChanged(EventArgsCache.ResetCollectionChanged);
}
#endregion Private Methods
//------------------------------------------------------
//
// Private Types
//
//------------------------------------------------------
#region Private Types
[Serializable]
private struct BlockReentrancyDisposable : IDisposable
{
private readonly ObservableCollection<T> _collection;
public BlockReentrancyDisposable(ObservableCollection<T> collection)
{
Debug.Assert(collection != null);
_collection = collection;
}
public void Dispose() => _collection._blockReentrancyCount--;
}
#endregion Private Types
//------------------------------------------------------
//
// Private Fields
//
//------------------------------------------------------
#region Private Fields
private int _blockReentrancyCount;
private IDisposable _boxedBlockReentrancyDisposable; // Lazily allocated only when a subclass calls BlockReentrancy().
#endregion Private Fields
}
internal static class EventArgsCache
{
internal static readonly PropertyChangedEventArgs CountPropertyChanged = new PropertyChangedEventArgs("Count");
internal static readonly PropertyChangedEventArgs IndexerPropertyChanged = new PropertyChangedEventArgs("Item[]");
internal static readonly NotifyCollectionChangedEventArgs ResetCollectionChanged = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset);
}
}

View File

@ -0,0 +1,152 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace System.Collections.ObjectModel
{
/// <summary>
/// Read-only wrapper around an ObservableCollection.
/// </summary>
[Serializable]
[DebuggerTypeProxy(typeof(CollectionDebugView<>))]
[DebuggerDisplay("Count = {Count}")]
public class ReadOnlyObservableCollection<T> : ReadOnlyCollection<T>, INotifyCollectionChanged, INotifyPropertyChanged
{
#region Constructors
//------------------------------------------------------
//
// Constructors
//
//------------------------------------------------------
/// <summary>
/// Initializes a new instance of ReadOnlyObservableCollection that
/// wraps the given ObservableCollection.
/// </summary>
public ReadOnlyObservableCollection(ObservableCollection<T> list) : base(list)
{
((INotifyCollectionChanged)Items).CollectionChanged += new NotifyCollectionChangedEventHandler(HandleCollectionChanged);
((INotifyPropertyChanged)Items).PropertyChanged += new PropertyChangedEventHandler(HandlePropertyChanged);
}
#endregion Constructors
#region Interfaces
//------------------------------------------------------
//
// Interfaces
//
//------------------------------------------------------
#region INotifyCollectionChanged
/// <summary>
/// CollectionChanged event (per <see cref="INotifyCollectionChanged" />).
/// </summary>
event NotifyCollectionChangedEventHandler INotifyCollectionChanged.CollectionChanged
{
add { CollectionChanged += value; }
remove { CollectionChanged -= value; }
}
/// <summary>
/// Occurs when the collection changes, either by adding or removing an item.
/// </summary>
/// <remarks>
/// see <seealso cref="INotifyCollectionChanged"/>
/// </remarks>
[field: NonSerialized]
protected virtual event NotifyCollectionChangedEventHandler CollectionChanged;
/// <summary>
/// raise CollectionChanged event to any listeners
/// </summary>
protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs args)
{
if (CollectionChanged != null)
{
CollectionChanged(this, args);
}
}
#endregion INotifyCollectionChanged
#region INotifyPropertyChanged
/// <summary>
/// PropertyChanged event (per <see cref="INotifyPropertyChanged" />).
/// </summary>
event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged
{
add { PropertyChanged += value; }
remove { PropertyChanged -= value; }
}
/// <summary>
/// Occurs when a property changes.
/// </summary>
/// <remarks>
/// see <seealso cref="INotifyPropertyChanged"/>
/// </remarks>
[field: NonSerialized]
protected virtual event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// raise PropertyChanged event to any listeners
/// </summary>
protected virtual void OnPropertyChanged(PropertyChangedEventArgs args)
{
if (PropertyChanged != null)
{
PropertyChanged(this, args);
}
}
#endregion INotifyPropertyChanged
#endregion Interfaces
#region Private Methods
//------------------------------------------------------
//
// Private Methods
//
//------------------------------------------------------
// forward CollectionChanged events from the base list to our listeners
private void HandleCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
OnCollectionChanged(e);
}
// forward PropertyChanged events from the base list to our listeners
private void HandlePropertyChanged(object sender, PropertyChangedEventArgs e)
{
OnPropertyChanged(e);
}
#endregion Private Methods
#region Private Fields
//------------------------------------------------------
//
// Private Fields
//
//------------------------------------------------------
#endregion Private Fields
}
}

View File

@ -0,0 +1,28 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Runtime.CompilerServices;
namespace System.Collections.Specialized
{
/// <summary>
/// A collection implementing this interface will notify listeners of dynamic changes,
/// e.g. when items get added and removed or the whole list is refreshed.
/// </summary>
public interface INotifyCollectionChanged
{
/// <summary>
/// Occurs when the collection changes, either by adding or removing an item.
/// </summary>
/// <remarks>
/// The event handler receives an argument of type
/// <seealso cref="System.Collections.Specialized.NotifyCollectionChangedEventArgs" />
/// containing data related to this event.
/// </remarks>
event NotifyCollectionChangedEventHandler CollectionChanged;
}
}

View File

@ -0,0 +1,465 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections;
using System.Diagnostics;
using System.Runtime.CompilerServices;
namespace System.Collections.Specialized
{
/// <summary>
/// This enum describes the action that caused a CollectionChanged event.
/// </summary>
public enum NotifyCollectionChangedAction
{
/// <summary> One or more items were added to the collection. </summary>
Add,
/// <summary> One or more items were removed from the collection. </summary>
Remove,
/// <summary> One or more items were replaced in the collection. </summary>
Replace,
/// <summary> One or more items were moved within the collection. </summary>
Move,
/// <summary> The contents of the collection changed dramatically. </summary>
Reset,
}
/// <summary>
/// Arguments for the CollectionChanged event.
/// A collection that supports INotifyCollectionChangedThis raises this event
/// whenever an item is added or removed, or when the contents of the collection
/// changes dramatically.
/// </summary>
public class NotifyCollectionChangedEventArgs : EventArgs
{
//------------------------------------------------------
//
// Constructors
//
//------------------------------------------------------
/// <summary>
/// Construct a NotifyCollectionChangedEventArgs that describes a reset change.
/// </summary>
/// <param name="action">The action that caused the event (must be Reset).</param>
public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action)
{
if (action != NotifyCollectionChangedAction.Reset)
throw new ArgumentException(SR.Format(SR.WrongActionForCtor, NotifyCollectionChangedAction.Reset), nameof(action));
InitializeAdd(action, null, -1);
}
/// <summary>
/// Construct a NotifyCollectionChangedEventArgs that describes a one-item change.
/// </summary>
/// <param name="action">The action that caused the event; can only be Reset, Add or Remove action.</param>
/// <param name="changedItem">The item affected by the change.</param>
public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, object changedItem)
{
if ((action != NotifyCollectionChangedAction.Add) && (action != NotifyCollectionChangedAction.Remove)
&& (action != NotifyCollectionChangedAction.Reset))
throw new ArgumentException(SR.MustBeResetAddOrRemoveActionForCtor, nameof(action));
if (action == NotifyCollectionChangedAction.Reset)
{
if (changedItem != null)
throw new ArgumentException(SR.ResetActionRequiresNullItem, nameof(action));
InitializeAdd(action, null, -1);
}
else
{
InitializeAddOrRemove(action, new object[] { changedItem }, -1);
}
}
/// <summary>
/// Construct a NotifyCollectionChangedEventArgs that describes a one-item change.
/// </summary>
/// <param name="action">The action that caused the event.</param>
/// <param name="changedItem">The item affected by the change.</param>
/// <param name="index">The index where the change occurred.</param>
public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, object changedItem, int index)
{
if ((action != NotifyCollectionChangedAction.Add) && (action != NotifyCollectionChangedAction.Remove)
&& (action != NotifyCollectionChangedAction.Reset))
throw new ArgumentException(SR.MustBeResetAddOrRemoveActionForCtor, nameof(action));
if (action == NotifyCollectionChangedAction.Reset)
{
if (changedItem != null)
throw new ArgumentException(SR.ResetActionRequiresNullItem, nameof(action));
if (index != -1)
throw new ArgumentException(SR.ResetActionRequiresIndexMinus1, nameof(action));
InitializeAdd(action, null, -1);
}
else
{
InitializeAddOrRemove(action, new object[] { changedItem }, index);
}
}
/// <summary>
/// Construct a NotifyCollectionChangedEventArgs that describes a multi-item change.
/// </summary>
/// <param name="action">The action that caused the event.</param>
/// <param name="changedItems">The items affected by the change.</param>
public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, IList changedItems)
{
if ((action != NotifyCollectionChangedAction.Add) && (action != NotifyCollectionChangedAction.Remove)
&& (action != NotifyCollectionChangedAction.Reset))
throw new ArgumentException(SR.MustBeResetAddOrRemoveActionForCtor, nameof(action));
if (action == NotifyCollectionChangedAction.Reset)
{
if (changedItems != null)
throw new ArgumentException(SR.ResetActionRequiresNullItem, nameof(action));
InitializeAdd(action, null, -1);
}
else
{
if (changedItems == null)
throw new ArgumentNullException(nameof(changedItems));
InitializeAddOrRemove(action, changedItems, -1);
}
}
/// <summary>
/// Construct a NotifyCollectionChangedEventArgs that describes a multi-item change (or a reset).
/// </summary>
/// <param name="action">The action that caused the event.</param>
/// <param name="changedItems">The items affected by the change.</param>
/// <param name="startingIndex">The index where the change occurred.</param>
public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, IList changedItems, int startingIndex)
{
if ((action != NotifyCollectionChangedAction.Add) && (action != NotifyCollectionChangedAction.Remove)
&& (action != NotifyCollectionChangedAction.Reset))
throw new ArgumentException(SR.MustBeResetAddOrRemoveActionForCtor, nameof(action));
if (action == NotifyCollectionChangedAction.Reset)
{
if (changedItems != null)
throw new ArgumentException(SR.ResetActionRequiresNullItem, nameof(action));
if (startingIndex != -1)
throw new ArgumentException(SR.ResetActionRequiresIndexMinus1, nameof(action));
InitializeAdd(action, null, -1);
}
else
{
if (changedItems == null)
throw new ArgumentNullException(nameof(changedItems));
if (startingIndex < -1)
throw new ArgumentException(SR.IndexCannotBeNegative, nameof(startingIndex));
InitializeAddOrRemove(action, changedItems, startingIndex);
}
}
/// <summary>
/// Construct a NotifyCollectionChangedEventArgs that describes a one-item Replace event.
/// </summary>
/// <param name="action">Can only be a Replace action.</param>
/// <param name="newItem">The new item replacing the original item.</param>
/// <param name="oldItem">The original item that is replaced.</param>
public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, object newItem, object oldItem)
{
if (action != NotifyCollectionChangedAction.Replace)
throw new ArgumentException(SR.Format(SR.WrongActionForCtor, NotifyCollectionChangedAction.Replace), nameof(action));
InitializeMoveOrReplace(action, new object[] { newItem }, new object[] { oldItem }, -1, -1);
}
/// <summary>
/// Construct a NotifyCollectionChangedEventArgs that describes a one-item Replace event.
/// </summary>
/// <param name="action">Can only be a Replace action.</param>
/// <param name="newItem">The new item replacing the original item.</param>
/// <param name="oldItem">The original item that is replaced.</param>
/// <param name="index">The index of the item being replaced.</param>
public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, object newItem, object oldItem, int index)
{
if (action != NotifyCollectionChangedAction.Replace)
throw new ArgumentException(SR.Format(SR.WrongActionForCtor, NotifyCollectionChangedAction.Replace), nameof(action));
InitializeMoveOrReplace(action, new object[] { newItem }, new object[] { oldItem }, index, index);
}
/// <summary>
/// Construct a NotifyCollectionChangedEventArgs that describes a multi-item Replace event.
/// </summary>
/// <param name="action">Can only be a Replace action.</param>
/// <param name="newItems">The new items replacing the original items.</param>
/// <param name="oldItems">The original items that are replaced.</param>
public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, IList newItems, IList oldItems)
{
if (action != NotifyCollectionChangedAction.Replace)
throw new ArgumentException(SR.Format(SR.WrongActionForCtor, NotifyCollectionChangedAction.Replace), nameof(action));
if (newItems == null)
throw new ArgumentNullException(nameof(newItems));
if (oldItems == null)
throw new ArgumentNullException(nameof(oldItems));
InitializeMoveOrReplace(action, newItems, oldItems, -1, -1);
}
/// <summary>
/// Construct a NotifyCollectionChangedEventArgs that describes a multi-item Replace event.
/// </summary>
/// <param name="action">Can only be a Replace action.</param>
/// <param name="newItems">The new items replacing the original items.</param>
/// <param name="oldItems">The original items that are replaced.</param>
/// <param name="startingIndex">The starting index of the items being replaced.</param>
public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, IList newItems, IList oldItems, int startingIndex)
{
if (action != NotifyCollectionChangedAction.Replace)
throw new ArgumentException(SR.Format(SR.WrongActionForCtor, NotifyCollectionChangedAction.Replace), nameof(action));
if (newItems == null)
throw new ArgumentNullException(nameof(newItems));
if (oldItems == null)
throw new ArgumentNullException(nameof(oldItems));
InitializeMoveOrReplace(action, newItems, oldItems, startingIndex, startingIndex);
}
/// <summary>
/// Construct a NotifyCollectionChangedEventArgs that describes a one-item Move event.
/// </summary>
/// <param name="action">Can only be a Move action.</param>
/// <param name="changedItem">The item affected by the change.</param>
/// <param name="index">The new index for the changed item.</param>
/// <param name="oldIndex">The old index for the changed item.</param>
public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, object changedItem, int index, int oldIndex)
{
if (action != NotifyCollectionChangedAction.Move)
throw new ArgumentException(SR.Format(SR.WrongActionForCtor, NotifyCollectionChangedAction.Move), nameof(action));
if (index < 0)
throw new ArgumentException(SR.IndexCannotBeNegative, nameof(index));
object[] changedItems = new object[] { changedItem };
InitializeMoveOrReplace(action, changedItems, changedItems, index, oldIndex);
}
/// <summary>
/// Construct a NotifyCollectionChangedEventArgs that describes a multi-item Move event.
/// </summary>
/// <param name="action">The action that caused the event.</param>
/// <param name="changedItems">The items affected by the change.</param>
/// <param name="index">The new index for the changed items.</param>
/// <param name="oldIndex">The old index for the changed items.</param>
public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, IList changedItems, int index, int oldIndex)
{
if (action != NotifyCollectionChangedAction.Move)
throw new ArgumentException(SR.Format(SR.WrongActionForCtor, NotifyCollectionChangedAction.Move), nameof(action));
if (index < 0)
throw new ArgumentException(SR.IndexCannotBeNegative, nameof(index));
InitializeMoveOrReplace(action, changedItems, changedItems, index, oldIndex);
}
/// <summary>
/// Construct a NotifyCollectionChangedEventArgs with given fields (no validation). Used by WinRT marshaling.
/// </summary>
internal NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, IList newItems, IList oldItems, int newIndex, int oldIndex)
{
_action = action;
_newItems = (newItems == null) ? null : new ReadOnlyList(newItems);
_oldItems = (oldItems == null) ? null : new ReadOnlyList(oldItems);
_newStartingIndex = newIndex;
_oldStartingIndex = oldIndex;
}
private void InitializeAddOrRemove(NotifyCollectionChangedAction action, IList changedItems, int startingIndex)
{
if (action == NotifyCollectionChangedAction.Add)
InitializeAdd(action, changedItems, startingIndex);
else if (action == NotifyCollectionChangedAction.Remove)
InitializeRemove(action, changedItems, startingIndex);
else
Debug.Assert(false, String.Format("Unsupported action: {0}", action.ToString()));
}
private void InitializeAdd(NotifyCollectionChangedAction action, IList newItems, int newStartingIndex)
{
_action = action;
_newItems = (newItems == null) ? null : new ReadOnlyList(newItems);
_newStartingIndex = newStartingIndex;
}
private void InitializeRemove(NotifyCollectionChangedAction action, IList oldItems, int oldStartingIndex)
{
_action = action;
_oldItems = (oldItems == null) ? null : new ReadOnlyList(oldItems);
_oldStartingIndex = oldStartingIndex;
}
private void InitializeMoveOrReplace(NotifyCollectionChangedAction action, IList newItems, IList oldItems, int startingIndex, int oldStartingIndex)
{
InitializeAdd(action, newItems, startingIndex);
InitializeRemove(action, oldItems, oldStartingIndex);
}
//------------------------------------------------------
//
// Public Properties
//
//------------------------------------------------------
/// <summary>
/// The action that caused the event.
/// </summary>
public NotifyCollectionChangedAction Action
{
get { return _action; }
}
/// <summary>
/// The items affected by the change.
/// </summary>
public IList NewItems
{
get { return _newItems; }
}
/// <summary>
/// The old items affected by the change (for Replace events).
/// </summary>
public IList OldItems
{
get { return _oldItems; }
}
/// <summary>
/// The index where the change occurred.
/// </summary>
public int NewStartingIndex
{
get { return _newStartingIndex; }
}
/// <summary>
/// The old index where the change occurred (for Move events).
/// </summary>
public int OldStartingIndex
{
get { return _oldStartingIndex; }
}
//------------------------------------------------------
//
// Private Fields
//
//------------------------------------------------------
private NotifyCollectionChangedAction _action;
private IList _newItems, _oldItems;
private int _newStartingIndex = -1;
private int _oldStartingIndex = -1;
}
/// <summary>
/// The delegate to use for handlers that receive the CollectionChanged event.
/// </summary>
public delegate void NotifyCollectionChangedEventHandler(object sender, NotifyCollectionChangedEventArgs e);
internal sealed class ReadOnlyList : IList
{
private readonly IList _list;
internal ReadOnlyList(IList list)
{
Debug.Assert(list != null);
_list = list;
}
public int Count
{
get { return _list.Count; }
}
public bool IsReadOnly
{
get { return true; }
}
public bool IsFixedSize
{
get { return true; }
}
public bool IsSynchronized
{
get { return _list.IsSynchronized; }
}
public object this[int index]
{
get
{
return _list[index];
}
set
{
throw new NotSupportedException(SR.NotSupported_ReadOnlyCollection);
}
}
public object SyncRoot
{
get { return _list.SyncRoot; }
}
public int Add(object value)
{
throw new NotSupportedException(SR.NotSupported_ReadOnlyCollection);
}
public void Clear()
{
throw new NotSupportedException(SR.NotSupported_ReadOnlyCollection);
}
public bool Contains(object value)
{
return _list.Contains(value);
}
public void CopyTo(Array array, int index)
{
_list.CopyTo(array, index);
}
public IEnumerator GetEnumerator()
{
return _list.GetEnumerator();
}
public int IndexOf(object value)
{
return _list.IndexOf(value);
}
public void Insert(int index, object value)
{
throw new NotSupportedException(SR.NotSupported_ReadOnlyCollection);
}
public void Remove(object value)
{
throw new NotSupportedException(SR.NotSupported_ReadOnlyCollection);
}
public void RemoveAt(int index)
{
throw new NotSupportedException(SR.NotSupported_ReadOnlyCollection);
}
}
}

View File

@ -0,0 +1,38 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Diagnostics;
namespace System.ComponentModel
{
/// <devdoc>
/// <para>Provides data for the <see langword='ErrorsChanged'/>
/// event.</para>
/// </devdoc>
public class DataErrorsChangedEventArgs : EventArgs
{
private readonly string _propertyName;
/// <devdoc>
/// <para>Initializes a new instance of the <see cref='System.ComponentModel.DataErrorsChangedEventArgs'/>
/// class.</para>
/// </devdoc>
public DataErrorsChangedEventArgs(string propertyName)
{
_propertyName = propertyName;
}
/// <devdoc>
/// <para>Indicates the name of the property whose errors changed.</para>
/// </devdoc>
public virtual string PropertyName
{
get
{
return _propertyName;
}
}
}
}

View File

@ -0,0 +1,18 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections;
namespace System.ComponentModel
{
public interface INotifyDataErrorInfo
{
bool HasErrors { get; }
IEnumerable GetErrors(string propertyName);
event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;
}
}

View File

@ -0,0 +1,11 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace System.ComponentModel
{
public interface INotifyPropertyChanged
{
event PropertyChangedEventHandler PropertyChanged;
}
}

View File

@ -0,0 +1,11 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace System.ComponentModel
{
public interface INotifyPropertyChanging
{
event PropertyChangingEventHandler PropertyChanging;
}
}

View File

@ -0,0 +1,38 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Diagnostics;
namespace System.ComponentModel
{
/// <devdoc>
/// <para>Provides data for the <see langword='PropertyChanged'/>
/// event.</para>
/// </devdoc>
public class PropertyChangedEventArgs : EventArgs
{
private readonly string _propertyName;
/// <devdoc>
/// <para>Initializes a new instance of the <see cref='System.ComponentModel.PropertyChangedEventArgs'/>
/// class.</para>
/// </devdoc>
public PropertyChangedEventArgs(string propertyName)
{
_propertyName = propertyName;
}
/// <devdoc>
/// <para>Indicates the name of the property that changed.</para>
/// </devdoc>
public virtual string PropertyName
{
get
{
return _propertyName;
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More