Pregunta

OK, así que quiero subclasificar ObservableCollection para agregarle una propiedad. Desafortunadamente, el evento PropertyChanged está protegido. Básicamente, quiero crear una subclase para tener un SelectedItem que pueda enlazar para las listas en mi aplicación MVVM WPF.

Aquí está el esqueleto de mi clase:

public class SelectableList<T> : ObservableCollection<T>
{
    public T SelectedItem {get;set;}
}

Pero no puedo hacer lo siguiente:

SelectableList<int> intList = new SelectableList<int>();
intList.PropertyChanged += new PropertyChangedEventHandler(intList_Changed);

debido a las restricciones de acceso. Esto me lleva a hacer una pregunta más profunda. ¿Por qué la IU puede recibir notificaciones de los eventos de PropertyChanged (por ejemplo, propiedad Count) y no puedo hacerlo en el código subyacente?

Mi cabeza está girando, ¿alguien puede iluminarme?

¿Fue útil?

Solución

SelectableList<int> intList = new SelectableList<int>();
((INotifyPropertyChanged)intList).PropertyChanged += 
    new PropertyChangedEventHandler(intList_Changed);

ObservableCollection implementa INotifyPropertyChanged explícitamente , lo que significa que debe enviar la instancia a la interfaz antes de poder acceder a los métodos, propiedades y eventos de la interfaz. En cuanto a por qué se hace esto, no lo sé. La extensión de marcado de enlace n no " ; saber " ObservableCollections o cualquier otro tipo. Comprueba los tipos para ver si implementan o extienden interfaces / clases base específicas (INPC, INCC, DependencyObject, etc.) y, por lo tanto, no le importa si la interfaz se implementa explícitamente.

Otros consejos

ObservableCollection (int .NET 3.5) parece implementar el evento PropertyChanged en un forma interesante .

protected event PropertyChangedEventHandler PropertyChanged;

event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged;

Esto significa que el evento protegido PropertyChanged es probable que solo se use para la implementación interna. El otro evento INotifyPropertyChanged.PropertyChanged es el que realmente cumple con la implementación de la interfaz INotifyPropertyChanged como interfaz explícita . Extrañamente, no veo ningún lugar dentro de ObservableCollection en el que INotifyPropertyChanged.PropertyChanged se genere. Esto puede indicar que se trata de un error en .NET 3.5, aunque no he probado para confirmar si, por ejemplo, se genera un evento de cambio de propiedad para el recuento cuando se agrega un elemento a una colección, pero parece ser cómo se supone que funciona. .

En la implementación de .NET 4.0, parece que el evento INotifyPropertyChanged.PropertyChanged en cambio se enlaza con el mismo delegado privado utilizado por el evento protegido PropertyChanged que puede haber sido un error fijar. También es posible que esto se deba a diferencias en cómo se manejan las implementaciones automáticas de eventos en .NET 4.0 .

Corrección: verifiqué que el evento INotifyPropertyChanged.PropertyChanged fue generado por ObservableCollection, por lo que las suposiciones que hice anteriormente se basan en los resultados del uso de Reflector para observar la implementación de ObservableCollection debe ser inexacto Supongo que el reflector está haciendo algo extraño. Aún no tengo pruebas de eso.

Por lo tanto, para que tu ejemplo funcione, deberías escribir para que esto funcione. El ejemplo que se muestra a continuación, tal como lo demostró Will en su respuesta.

SelectableList<int> intList = new SelectableList<int>();
((INotifyPropertyChanged)intList).PropertyChanged += 
    new PropertyChangedEventHandler(intList_Changed);

Interesante ¿verdad? El uso de interfaces explícitas se utiliza principalmente para evitar colisiones inevitables en los miembros requeridos para una interfaz determinada, pero se pueden usar para ocultar la existencia de un miembro en un sentido.

Si desea aumentar los eventos de cambio de propiedad para sus propias propiedades personalizadas que introduce en su subclase, considere la posibilidad de anular y / o llamar al método protegido OnPropertyChanged que ObservableCollection también implementa. Esta técnica es un estándar bien adoptado y permite a las subclases generar eventos o manejar eventos sin tener acceso al delegado de eventos subyacente. En general, es preferible usar esta técnica también por cierto, en lugar de tener una subclase enganche los controladores de eventos a sus propios eventos de clases base. Para más ejemplos, vea cómo se implementan los eventos en varios controles en WinForms y WPF.

Intenté agregar una nueva propiedad en

public class ResultCollection<T> : ObservableCollection<T>
{

        Boolean _val;
        public Boolean Val
        {   
            get
            {   
                return _val;
            }
            set
            {   
                _val= value;
                OnPropertyChanged(new PropertyChangedEventArgs("Val"));
            }
        }
}

Realmente no me di cuenta de que PropertyChanged se define como protegido . Finalmente moví la propiedad Val a ViewModel.

La interfaz de usuario puede y recibe una notificación. Esta es una restricción JUST con ObservableCollection, que define el evento PropertyChanged como protegido.

FWIW, creo que es mejor dejar solo ObservableCollection y simplemente agregar otra propiedad a su máquina virtual.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top