Stale Fragen verdienen frische Antworten :)
eine Klasse von ListCollectionView
ist der Weg Ableitung I durch AddNew
als auch hinzugefügt werden die Objekte zu steuern nahm, aber nach der ListCollectionView
durch die Quelle des Surfens finde heraus, was es intern tut, fand ich, dass der sicherste Weg, AddNew
(es ist technisch ein Override) neu zu definieren ist, ListCollectionView.AddNewItem
nach dem Erstellen meines neuen Objekts zu verwenden, so würde Ihr Code wie folgt aussehen:
public class CustomView : ListCollectionView, IEditableCollectionView
{
public CustomView(System.Collections.IList list)
: base(list)
{
}
object IEditableCollectionView.AddNew()
{
DerivedB obj = new DerivedB();
return base.AddNewItem(obj);
}
}
Das funktioniert gut, weil zusätzlich sonst nahezu identische Implementierungen AddNewCommon(object newItem)
, ListCollectionView.AddNew()
und ListCollectionView.AddNewItem(object item)
beide Aufruf mit:
public object AddNew()
{
VerifyRefreshNotDeferred();
if (IsEditingItem)
{
CommitEdit(); // implicitly close a previous EditItem
}
CommitNew(); // implicitly close a previous AddNew
if (!CanAddNew)
throw new InvalidOperationException(SR.Get(SRID.MemberNotAllowedForView, "AddNew"));
return AddNewCommon(_itemConstructor.Invoke(null));
}
public object AddNewItem(object newItem)
{
VerifyRefreshNotDeferred();
if (IsEditingItem)
{
CommitEdit(); // implicitly close a previous EditItem
}
CommitNew(); // implicitly close a previous AddNew
if (!CanAddNewItem)
throw new InvalidOperationException(SR.Get(SRID.MemberNotAllowedForView, "AddNewItem"));
return AddNewCommon(newItem);
}
AddNewCommon
ist, wo alle die wirkliche Magie geschieht; Ereignisse, ruft BeginInit
und BeginEdit
auf das neue Element Brennen, wenn unterstützt, und schließlich durch Rückrufe auf dem Datagrid, zur Festlegung der Zellbindungen:
object AddNewCommon(object newItem)
{
_newItemIndex = -2; // this is a signal that the next Add event comes from AddNew
int index = SourceList.Add(newItem);
// if the source doesn't raise collection change events, fake one
if (!(SourceList is INotifyCollectionChanged))
{
// the index returned by IList.Add isn't always reliable
if (!Object.Equals(newItem, SourceList[index]))
{
index = SourceList.IndexOf(newItem);
}
BeginAddNew(newItem, index);
}
Debug.Assert(_newItemIndex != -2 && Object.Equals(newItem, _newItem), "AddNew did not raise expected events");
MoveCurrentTo(newItem);
ISupportInitialize isi = newItem as ISupportInitialize;
if (isi != null)
{
isi.BeginInit();
}
IEditableObject ieo = newItem as IEditableObject;
if (ieo != null)
{
ieo.BeginEdit();
}
return newItem;
}
Hier habe ich den Quellcode meiner TypedListCollectionView
enthalten habe, die ich benutze steuert die AddNew
Verhalten, wenn ich nicht weiß, welche Art wird zur Entwurfszeit benötigt:
public class TypedListCollectionView : ListCollectionView, IEditableCollectionView
{
Type AddNewType { get; set; }
public TypedListCollectionView(System.Collections.IList source, Type addNewType)
: base(source)
{
AddNewType = addNewType;
}
object IEditableCollectionView.AddNew()
{
object newItem = Activator.CreateInstance(AddNewType);
return base.AddNewItem(newItem);
}
}
ich diesen Ansatz mag, da es ein Maximum an Flexibilität für den Fall vorsieht, wenn AddNew
‚s Art muß von zur Laufzeit angepasst werden eins zum anderen. Es ermöglicht auch AddNew
, um das erste Element in der Auflistung hinzuzufügen, was praktisch ist, wenn die Listenquelle anfänglich leer ist, aber der zugrunde liegende Typ kann bestimmt werden.
This link diskutiert eine alternative Möglichkeit, den Typ zu erzwingen, der von AddNew()
verwendet wird. Es verwendet Reflektion, um die private _itemConstructor
-Eigenschaft, die von AddNew
10 verwendet wird, auf einen parameterlosen Konstruktor eines angegebenen Typs festzulegen.Dies wäre besonders nützlich, wenn Ihr ListCollectionView
von einer Komponente kommt, die außerhalb Ihres Einflusses liegt, oder Sie Funktionalität in bestehenden Code hinzufügen müssen und Sie sind besorgt über das Brechen von Dingen (was ich nie bin, weil ich ein Kavalier-Codierer bin, der schwielig Karossen mit Sammlungen).
Ich habe die Architektur in meiner Anwendung so geändert, dass dies für mich kein Problem mehr ist, aber Ihre Antwort erscheint plausibel, wenn Sie sie nur ansehen. –
Aus irgendeinem Grund scheint ich diese Antwort im letzten Jahr nicht akzeptiert zu haben. –