¿Crear ViewModels con propiedades comunes con OnPropertyChanged?

Me di cuenta de que tengo muchos modelos ver modelos con esas dos propiedades

public Visibility OkButtonVisibility
{
get{  return _OkButtonVisibility;}
set{ 
_OkButtonVisibility = value;
RaisePropertyChanged("OkButtonVisibility");
}

}

public Visibility CancelButtonVisibility
{
get{  return _CancelButtonVisibility;}
set{ 
_CancelButtonVisibility = value;
RaisePropertyChanged("CancelButtonVisibility");
}

}

Quería crear una interfaz adjunta para ellos de esta manera:

Interface IOKandCancelButtonsVM
{
 public Visibility OkButtonVisibility
{
get{  return _OkButtonVisibility;}
set{ 
_OkButtonVisibility = value;
RaisePropertyChanged("OkButtonVisibility");
}

}

public Visibility CancelButtonVisibility
{
get{  return _CancelButtonVisibility;}
set{ 
_CancelButtonVisibility = value;
RaisePropertyChanged("CancelButtonVisibility");
}

}

y tengo mis modelos de vista que usan esto para heredarlos y otras interfaces con propiedades de proxy como esta

class VM1:BaseVM,IOKandCancelButtonsVM,IOtherCommonPropertyVM
{ 

} 

pero luego revelé que mis nuevas interfaces no se implementan INotifyChanged. sería una mala idea tenerIOKandCancelButtonsVM implicación INotifyChanged y tienen VM1 implicar explícitamente BaseVM?

Nunca traté con la clase que heredaba la misma interfaz dos veces y no estaba seguro de qué hacer.

esto es solo un ejemplo, menos de la mitad de las máquinas virtuales usan las que tengo, algunos cientos de propiedades, muchas compartidas en docenas de pantallas. Necesito una solución más elegante que pegar todo eso en BaseViewModel

preguntado el 01 de julio de 12 a las 08:07

erm ¿por qué -1 sin comentarios? esta mal formulada la pregunta? -

4 Respuestas

No puede tener una implementación en su definición de interfaz. Esto significa que su IOKandCancelButtonsVM la definición es incorrecta.

¿Sería una mala idea que IOKandCancelButtonsVM implemente BaseVM?

Sí, sería una muy mala idea, imposible de hecho, las interfaces no pueden implementar o extender clases.

Dado que solicitó una opinión sobre cómo estructurar su código, también arrojaré esto: elimine cualquier referencia a 'visibilidad' de su modelo de vista. No devuelva un valor System.Visibility de su modelo de vista.

Un modelo de vista no debería saber nada sobre la vista. La forma semánticamente correcta de hacer esto es simplemente devolver una bandera del modelo de vista y usar un convertidor para cambiarlo a un valor de Visibilidad en el enlace; incluso hay un convertidor listo para usar en el marco para hacer esto: BooleanToVisibilityConverterBooleanToVisibilityConverter. Trate de evitar cualquier mención de términos relacionados con la interfaz de usuario en su máquina virtual, incluso si está devolviendo un bool; es una buena práctica que conduce a un código más estricto y disciplinado, usar esos nombres de cualquier manera eventualmente conducirá a un código maloliente.

Tengo una publicación de blog que ilustra un buen enfoque para las notificaciones de cambio de propiedad: Optimización de las notificaciones de propiedades en MVVM.

Solo para que quede claro, le aconsejo que se deshaga de cualquier idea que tenga sobre IOKandCancelButtonsVM Las interfaces, por supuesto, incluyen propiedades booleanas simples en un modelo de vista base que se ampliará con muchos otros modelos de vista que estarán vinculados a cuadros de diálogo con botones Aceptar/Cancelar.

Para diagramar esto en el texto, se vería así:

TuBaseVm <- BaseVmUsedByDialogs <-- SpecificDialogVm

(tenga en cuenta la cursiva que indica que la clase es abstracta)

Respondido 01 Jul 12, 09:07

eso no responde mi pregunta y por supuesto quise decir implementar INotifyChanged - Nahum

@NahumLitvin: he agregado un enlace útil. Mi respuesta aborda gran parte de su pregunta y señala problemas con su enfoque actual: ¿qué es lo que no entiende? - babosa

hay un pequeño problema con su enfoque llamado. ENORME proyecto ENORME lleno de diseño horrible. es demasiado tarde para arreglarlo. todo lo que puedo hacer es tratar de mejorar un poco la situación. mi enfoque se puede obtener con varios extractos para hacer clic en la interfaz. requiere semanas de reescritura. - Nahum

@NahumLitvin Simpatizo con el enorme diseño horrible, sin embargo, aún puede usar este enfoque con las cosas nuevas y luego convertir fácilmente las máquinas virtuales existentes a este enfoque también. La refactorización generalmente implica cambiar la herencia de la clase de VM para usar las nuevas VM base y eliminar el código redundante que implementan las VM base. He tenido que hacer exactamente esto en el pasado, puede ser tedioso pero no es particularmente difícil de hacer. - babosa

Parece que ya tiene una clase de modelo de vista base. Simplemente agregue las dos propiedades allí. Es posible que desee crear una segunda base que herede de la primera, que usará cuando se requieran esas dos propiedades, por lo que, en caso de que no lo sean, no hay gastos generales.

Respondido 01 Jul 12, 08:07

menos de la mitad de las máquinas virtuales usan las que tengo unos pocos cientos de propiedades, muchas compartidas en docenas de pantallas. Necesito una solución más general - Nahum

¿Por qué no ir por virtual properties en su clase base BaseVM con la funcionalidad predeterminada implementada en ella. En caso de que otras clases derivadas quieran extenderlo, siempre pueden anularlo según lo requiera la funcionalidad.

Asegúrese de que su BaseVM esté implementando INotifyPropertyChanged.

Respondido 01 Jul 12, 09:07

Simplemente crearía una clase base abstracta y heredaría los ViewModels que necesitan esas propiedades. Mantenlo simple.

abstract class BaseDialogVM : BaseVM
{
    private Visibility _OkButtonVisibility;
    public Visibility OkButtonVisibility {
        get { return _OkButtonVisibility; }
        set { 
           _OkButtonVisibility = value;
           RaisePropertyChanged("OkButtonVisibility");
        }
    }

    private Visibility _CancelButtonVisibility;
    public Visibility CancelButtonVisibility {
        get { return _CancelButtonVisibility; }
        set { 
           _CancelButtonVisibility = value;
           RaisePropertyChanged("CancelButtonVisibility");
        }
    }
}

class VM1 : BaseDialogVM { /*...*/ }

Respondido 02 Jul 12, 06:07

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.