9

Tengo un control genérico que muestra un editor basado en la propiedad type dentro de un ViewModel. Actualmente se implementa utilizando Control, ControlTemplate y DataTrigger como esto -ControlTemplate con DataTrigger vs. DataTemplate con DataTemplateSelector

<Control 
    x:Name="MainControl" 
    Grid.Column="1" 
    TargetUpdated="OnTargetUpdated"> 
     <Control.Style> 
      <Style> 
       <Style.Triggers> 
        <DataTrigger 
         Binding="{Binding Path=EditorType}" 
         Value="{x:Static view:EditorType.Bool}"> 
         <Setter 
          Property="Control.Template" 
          Value="{StaticResource boolTemplate}" /> 
        </DataTrigger> 
        <DataTrigger 
         Binding="{Binding Path=EditorType}" 
         Value="{x:Static view:EditorType.Text}"> 
         <Setter 
          Property="Control.Template" 
          Value="{StaticResource textTemplate}" /> 
        </DataTrigger> 
        <DataTrigger 
         Binding="{Binding Path=EditorType}" 
         Value="{x:Static view:EditorType.Integer}"> 
         <Setter 
          Property="Control.Template" 
          Value="{StaticResource integerTemplate}" /> 
        </DataTrigger> 
        ... 
        .... 
       </Style.Triggers> 
      </Style> 
    </Control.Style> 
</Control> 

Ahora, puede conseguir lo mismo usando ContentPresenter, DataTemplate y DataTemplateSelector como esto -

<local:EditorTemplateSelector 
    BoolEditorTemplate="{StaticResource boolTemplate}" 
    TextEditorTemplate="{StaticResource textTemplate}" 
    IntegerEditorTemplate="{StaticResource integerTemplate}" 
    ... 
    .... 
    x:Key="EditorTemplateSelector"> 
</local:EditorTemplateSelector> 

<ContentPresenter 
    ContentTemplateSelector="{Binding Source={StaticResource EditorTemplateSelector}}" 
    Content="{Binding}" 
    TargetUpdated="OnTargetUpdated"> 
</ContentPresenter> 

// Template selector returning appropriate template based on type 

me siento el segundo enfoque, utilizando DataTemplateSelector es mejor, pero me gustaría saber de usted -

  • ¿Cuál es mejor y por qué?

  • ¿Habrá alguna diferencia de rendimiento en dos?

+0

Según lo que he visto, la segunda forma se considera la mejor práctica. También es mucho más legible ya que no mantiene la lógica de selección (que siempre debe definirse en C#). Sin embargo, también estoy interesado en el punto de rendimiento. –

Respuesta

9

He oído que DataTemplateSelectors No actualizar la plantilla si el valor que están basadas en los cambios, y debido a esto por lo general no se utilicen.

Mi método preferido es utilizar DataTemplates.

<MyControl.Resources> 
    <DataTemplate TargetType="{x:Type local:BooleanModel}"> 
     <local:BooleanView /> 
    </DataTemplate> 
    <DataTemplate TargetType="{x:Type local:IntegerModel}"> 
     <local:IntegerView /> 
    </DataTemplate> 
    ... 
</MyControl.Resources> 

En segundo lugar, si quiero cambiar la plantilla sobre la base de una propiedad en lugar del tipo de objeto, que tienden a utilizar DataTriggers. Esto se debe a que si esa propiedad se cambia alguna vez, la notificación PropertyChange le indicará automáticamente a la UI que ha cambiado y actualizará la plantilla. No creo que DataTemplateSelectors haga esto automáticamente. También prefiero ver la lógica de selección de plantilla en mi XAML, no tenerla oculta en un archivo TemplateSelector, pero eso es solo una preferencia personal.

Y mi última opción es usar un DataTemplateSelector. Casi nunca uso uno en una aplicación WPF, aunque lo hago a menudo en Silverlight porque no es compatible con mi método preferido de usar implícito DataTemplates (todavía)

No conozco ninguna diferencia de rendimiento significativa entre los dos, aunque Me interesaría si alguien pudiera decirme lo contrario.

+0

Interesante, estoy casi seguro de que la pregunta era sobre WPF, solo por curiosidad: arreglaron plantillas implícitas en SL4/5 porque sé que no estaban disponibles en las versiones previas. –

+0

@Dmitry Creo que el último proyecto de Silverlight que hice fue en 4.0, y las plantillas de datos implícitas no funcionaron en ese momento. Escuché que funcionan en 5.0, pero aún no lo han hecho. – Rachel

+0

+1 para 'DataTemplateSelectors no actualiza la plantilla si el valor está basado en chan'. Lo comprobé y la plantilla no se actualiza si el valor cambia. Gracias. – akjoshi

3

Tienes dos preguntas aquí :)

  1. Dónde presentar el decsion en XAML (DataTriggers) o en el código TemplateSelector
  2. ¿Qué estás todo el sobreescribiendo Style o simplemente el DataTemplate. En su primera muestra anula Style, en la segunda - DataTemplate.

Acá mi 2c:

me quedo con los factores desencadenantes, como se obtendrá un nivel de flexibilidad inmejorable con ellos - un nuevo editor para el precio del nuevo recurso y un disparador en toda XAML: ¿qué puede ser mejor? Existe una advertencia potencial relacionada con el uso del DataTrigger: puede causar filtraciones de datos.

Hablando de Style vs DataTemplate elección I volver a pegar con el Style. Puede ser un árbol visual algo más pesado, pero te dará el control final sobre la apariencia de tus editores.

En particular, algunas propiedades solo se pueden definir en un nivel Style, usando StyleSetters. Definir entonces @DataTemplate nivel simplemente no funcionará ya que su contenido DataTemplate no es un elemento secundario de su contenedor de control (hay un nivel extra - el control de actula). Si no tiene tales propiedades, ControlTemplates también son buenas y probablemente más rápidas (?).

+0

Gracias Dmitry, ¿me puede dar más detalles sobre 'DataTrigger causando filtraciones de datos? – akjoshi

+0

@akjoshi - Lo siento, no podré encontrar una reproducción exacta, esta es más bien una observación, he visto algunos proyectos que se benefician gratamente después de reducir la cantidad de desencadenantes. –

0

Sugeriría que la respuesta es más de lo que crees que es necesario control. Obtiene un montón de funcionalidades con un control que no está realmente disponible con un DataTemplate. Puede agregar DependencyProperties, events, functions, etc. ¿Pero necesita esto? Si no lo hace, entonces un control puede ser excesivo.

Cuestiones relacionadas