/// <summary> /// Finds the given key searching on all items for the specified property. /// If the property is an indexed property the index is used for faster searching. /// </summary> /// <param name="property">The property to look at.</param> /// <param name="key">The key to search.</param> /// <returns>The inedex of the first item the match the given key.</returns> public int Find(PropertyDescriptor property, object key) { int index = -1; if (this.propertiesIndexes.ContainsKey(property.Name)) { /* * Se la proprietà è indicizzata facciamo fare all'indice */ Dictionary <Object, IEntityItemView <T> > propertyIndex = this.propertiesIndexes[property.Name]; if (propertyIndex.ContainsKey(key)) { IEntityItemView <T> item = propertyIndex[key]; index = this.IndexOf(item); } } else { /* * Altrimenti ci tocca scorrere tutta la lista, * recuperare via reflection il valore e confrontarlo * * Utilizziamo Object.Equals() e non == perchè se i tipi sono * ValueType vengono boxati e == confronterebe le reference */ var item = this.Where(element => Object.Equals(property.GetValue(element.EntityItem), key)).FirstOrDefault(); if (item != null) { index = this.IndexOf(item); } } return(index); }
protected override object GetValueCore(IEntityItemView <T> component) { var args = new EntityItemViewValueGetterArgs <T, TValue>(component, this.Name); var returnValue = this.ValueGetter(args); return(returnValue); }
/// <summary> /// Removes the corrurrence of the EntityItemView at the specified index /// </summary> /// <param name="index">The index.</param> public void RemoveAt(int index) { IEntityItemView <T> item = this.storage[index]; if (this.defaultIndex.ContainsKey(item)) { this.defaultIndex.Remove(item); } this.storage.RemoveAt(index); }
//Radical.Reflection.Function<Object> fastGetter = null; protected virtual object GetValueCore(IEntityItemView <T> component) { //if( fastGetter == null ) //{ // fastGetter = Radical.Reflection.ObjectExtensions.CreateFastPropertyGetter( component.EntityItem, this.Property ); //} //return fastGetter(); return(this.Property.GetValue(component.EntityItem, null)); }
/// <summary> /// Removes the first occurrence of a specific object from the <see cref="T:System.Collections.Generic.ICollection`1"/>. /// </summary> /// <param name="item">The object to remove from the <see cref="T:System.Collections.Generic.ICollection`1"/>.</param> /// <returns> /// true if <paramref name="item"/> was successfully removed from the <see cref="T:System.Collections.Generic.ICollection`1"/>; otherwise, false. This method also returns false if <paramref name="item"/> is not found in the original <see cref="T:System.Collections.Generic.ICollection`1"/>. /// </returns> /// <exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.ICollection`1"/> is read-only.</exception> public bool Remove(IEntityItemView <T> item) { int index = this.storage.IndexOf(item); if (index > -1) { this.RemoveAt(index); return(true); } return(false); }
/// <summary> /// Given the Index of an EntityItemView, in the View, returns the Index /// of the encapsulated T element in the DataSource, otherwise -1. /// </summary> /// <param name="objectItemViewIndexInView">The EntityItemView index.</param> /// <returns>The index of the T element, otherwise -1</returns> public int FindObjectIndexInDataSource(int objectItemViewIndexInView) { if (objectItemViewIndexInView > -1 && objectItemViewIndexInView < this.storage.Count) { IEntityItemView <T> el = this.storage[objectItemViewIndexInView]; if (el != null) { return(defaultIndex[el]); } } return(-1); }
/// <summary> /// Adds an item to the <see cref="T:System.Collections.Generic.ICollection`1"/>. /// </summary> /// <param name="item">The object to add to the <see cref="T:System.Collections.Generic.ICollection`1"/>.</param> /// <exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.ICollection`1"/> is read-only.</exception> public void Add(IEntityItemView <T> item) { this.storage.Add(item); /* * In fase di insert di un nuovo elemento * aggiungiamo l'elemento anche al nostro * indice, l'item lo recuperiamo dalla * List che fa da storage per la View. * * Se l'elemento che stiamo inserendo è un nuovo elemento * questo non sarà ancora presente nella List quindi giustamente * viene inserito con Value a -1 */ this.defaultIndex.Add(item, this.view.DataSource.IndexOf(item.EntityItem)); }
/// <summary> /// When overridden in a derived class, gets the current value of the property on a component. /// </summary> /// <param name="component">The component with the property for which to retrieve the value.</param> /// <returns> /// The value of a property for a given component. /// </returns> public override sealed object GetValue(object component) { if (component == null) { throw new ArgumentNullException("component"); } IEntityItemView <T> oiv = component as IEntityItemView <T>; if (oiv == null) { throw new ArgumentException("InvalidComponentType", "component"); } return(this.GetValueCore(oiv)); }
/// <summary> /// When overridden in a derived class, sets the value of the component to a different value. /// </summary> /// <param name="component">The component with the property value that is to be set.</param> /// <param name="value">The new value.</param> public override sealed void SetValue(object component, object value) { if (this.IsReadOnly) { throw new InvalidOperationException("Current property is readonly."); } if (component == null) { throw new ArgumentNullException("component"); } IEntityItemView <T> oiv = component as IEntityItemView <T>; if (oiv == null) { throw new ArgumentException("InvalidComponentType", "component"); } this.SetValueCore(oiv, value); }
/// <summary> /// Compares two objects and returns a item indicating whether one is less than, equal to, or greater than the other. /// </summary> /// <param name="x">The first object to compare.</param> /// <param name="y">The second object to compare.</param> /// <returns> /// Value Condition Less than zero<paramref name="x" /> is less than <paramref name="y" />.Zero<paramref name="x" /> equals <paramref name="y" />.Greater than zero<paramref name="x" /> is greater than <paramref name="y" />. /// </returns> protected virtual int OnCompare(IEntityItemView <T> x, IEntityItemView <T> y) { /* * Il confronto viene fatto scorrendo tutti * i ListSortDescription... * * Diventa necessario confrontare i criteri successivi * solo se il precedente non ha dato risultati utili, cioè * i due valori confrontati sono uguali... * * Il classico esempio è Cognome ASC, Nome DESC confronto i * nomi solo se i Cognomi sono uguali */ int retVal = 0; if (this.SortDescriptions.Count == 1) { ListSortDescription sd = this.SortDescriptions[0]; object valueX = sd.PropertyDescriptor.GetValue(x); object valueY = sd.PropertyDescriptor.GetValue(y); retVal = EntityItemViewSortComparer <T> .Compare(valueX, valueY, sd.SortDirection); } else { foreach (ListSortDescription sd in this.SortDescriptions) { if (retVal == 0) { object valueX = sd.PropertyDescriptor.GetValue(x); object valueY = sd.PropertyDescriptor.GetValue(y); retVal = EntityItemViewSortComparer <T> .Compare(valueX, valueY, sd.SortDirection); } } } return(retVal); }
public int Compare(IEntityItemView <T> x, IEntityItemView <T> y) { /* * Questo comparer ha lo scopo di ordinare gli item come sono * nella data source... quindi per prima cosa recuperiamo l'indice * nella DataSource l'implementazione di default del confronto * fra indici ci va benissimo tranne per il fatto è che presumibile * che un EntityItem non esista ancora nella DataSource perchè non * è stato ancora "Committed" in qusto caso il compare di default * ce lo metterebbe in testa perchè l'indice -1 è minore... ergo * dobbiamo gestire questo "special case" */ int xIndex = this.dataSource.IndexOf(x.EntityItem); int yIndex = this.dataSource.IndexOf(y.EntityItem); if (xIndex == -1 && yIndex != -1) { /* * x non c'è, lo dobbiamo mettere comunque in fondo * --> x è più grande di y */ return(-1); } else if (xIndex != -1 && yIndex == -1) { /* * y non c'è, lo dobbiamo mettere comunque in fondo * --> x è più grande di y */ return(1); } else { return(xIndex.CompareTo(yIndex)); } }
public EntityItemViewValueGetterArgs(IEntityItemView <T> item, string propertyName) : base(item, propertyName) { }
/// <summary> /// Rebuilds all the Indexes. /// </summary> public void Rebuild() { IEnumerable <KeyValuePair <IEntityItemView <T>, int> > pendingAddElements = null; if (this.Count > 0) { /* * Dato che verranno ricreati da zero tutti gli elementi * presenti nella EntityView, sganciamo i gestori degli * eventi degli elementi attualmente presenti. */ this.storage.ForEach(element => { this.view.OnUnwireEntityItemView(element); }); /* * Dato che è possibile che ci siano elementi nuovi * non ancora inseriti nella DataSource sottostante * dobbiamo tenerne traccia prima di rimuovere tutti * gli elementi presenti, quindi aggiungiamo gli elementi * non presenti nella DataSource sottostante ad una cache * temporanea. Gli elementi non presenti sono quelli che * nel defaultIndex hanno un Value pari a -1 * Il "ToList()" è necessario per scatenare subito il deferred * loading altrimenti ci perdiamo i pezzi per strada con la clear. */ pendingAddElements = this.defaultIndex.Where(element => element.Value == -1).AsReadOnly(); /* * Svuotiamo questa istanza */ this.Clear(); } /* * Creiamo una lista, di tuple (Anonymous Type), che tiene traccia * di tutti gli elementi nella DataSource che devono essere reinsiriti e del * loro indice relativo alla DataSource, se un elemento è in stato * PendingAdd non sarà ancora presente nella DataSource quindi correttamente * verrà aggiunto con Value a -1 */ var sourceElements = ((IEnumerable <T>) this.view.DataSource) .Where(element => this.view.Filter.ShouldInclude(element)) .Select(element => new { Element = (T)element, Index = this.view.DataSource.IndexOf(element) }); /* * Scorriamo tutti gli elementi trovati, creiamo un nuovo * EntityItemView agganciamo gli eventi che ci interessano * e lo reinseriamo nell'indice */ sourceElements.ForEach(sourceElement => { IEntityItemView <T> item = this.view.CreateEntityItemView(sourceElement.Element); this.view.OnWireEntityItemView(item); this.Add(item); }); sourceElements = null; if (pendingAddElements != null && pendingAddElements.Any()) { /* * Riaggiungiamo gli elementi che erano in pending add */ pendingAddElements.ForEach(element => { IEntityItemView <T> item = element.Key; this.view.OnWireEntityItemView(item); this.Add(item); }); } pendingAddElements = null; this.ApplySort(); if (this.propertiesIndexes.Count > 0) { /* * Ci sono proprietà indicizzate * dobbiamo ricostruire anche questi * indici */ this.propertiesIndexes.ForEach(index => { /* * Ricostruiamo il PropertyDescriptor * e reindicizziamo la proprietà */ PropertyDescriptor property = TypeDescriptor.GetProperties(typeof(T)).Find(index.Key, false); this.IndexProperty(property, index.Value); }); } }
/// <summary> /// Return the index of an EntityItemView in the View. /// </summary> /// <param name="item">The item.</param> /// <returns></returns> public int IndexOf(IEntityItemView <T> item) { return(this.storage.IndexOf(item)); }
public EntityItemViewValueSetterArgs(IEntityItemView <T> item, string propertyName, TValue value) : base(item, propertyName) { this.Value = value; }
protected virtual void SetValueCore(IEntityItemView <T> component, object value) { this.Property.SetValue(component.EntityItem, value, null); }
/// <summary> /// Determines whether the <see cref="T:System.Collections.Generic.ICollection`1"/> contains a specific item. /// </summary> /// <param name="item">The object to locate in the <see cref="T:System.Collections.Generic.ICollection`1"/>.</param> /// <returns> /// true if <paramref name="item"/> is found in the <see cref="T:System.Collections.Generic.ICollection`1"/>; otherwise, false. /// </returns> public bool Contains(IEntityItemView <T> item) { return(this.storage.Contains(item)); }
/// <summary> /// Compares two objects and returns a item indicating whether one is less than, equal to, or greater than the other. /// </summary> /// <param name="x">The first object to compare.</param> /// <param name="y">The second object to compare.</param> /// <returns> /// Value Condition Less than zero<paramref name="x"/> is less than <paramref name="y"/>.Zero<paramref name="x"/> equals <paramref name="y"/>.Greater than zero<paramref name="x"/> is greater than <paramref name="y"/>. /// </returns> public int Compare(IEntityItemView <T> x, IEntityItemView <T> y) { return(this.OnCompare(x, y)); }
protected EntityItemViewValueArgs(IEntityItemView <T> item, string propertyName) { this.Item = item; this.PropertyName = propertyName; }
protected override void SetValueCore(IEntityItemView <T> component, object value) { var args = new EntityItemViewValueSetterArgs <T, TValue>(component, this.Name, (TValue)value); this.ValueSetter(args); }