2009-04-02 15 views
8

El DataTemplate predeterminado en una aplicación wpf muestra el resultado del método .ToString(). Estoy desarrollando una aplicación donde el DataTemplate predeterminado no debería mostrar nada.Especifique un DataTemplate vacío predeterminado en lugar del predeterminado 'ToString()' DataTemplate

que he probado:

<Grid.Resources> 
    <DataTemplate DataType="{x:Type System:Object}"> 
    <Grid></Grid> 
    </DataTemplate> 
</Grid.Resources> 

Pero esto no funciona. ¿Alguien sabe si esto es posible sin especificar un DataTemplate específico para cada tipo de clase en la aplicación?

Respuesta

4

Sé de ninguna manera para hacer esto. Según el comentario de Joe a continuación, WPF específicamente no permite especificar un DataTemplate para el tipo Object.

Dependiendo de sus requisitos exactos, puede ser más fácil buscar un DataTemplate que coincida con el tipo específico. Si encuentras uno, úsalo. De lo contrario, no mostrar nada. Por ejemplo:

<ContentControl Content="{Binding YourContent}" ContentTemplateSelector="{StaticResource MyContentTemplateSelector}"/> 

Y en el selector (pseudo-código, obviamente):

var dataTemplateKey = new DataTemplateKey() { DataType = theType; }; 
var dataTemplate = yourControl.FindResource(dataTemplateKey); 

if (dataTemplate != null) 
{ 
    return dataTemplate; 
} 

return NulloDataTemplate; 
+2

"WPF coincide con un objeto con su DataTemplate por tipo de tiempo de ejecución exacta" - No es cierto. Si agrega un DataTemplate con DataType = BaseClass, también coincidirá con SubClass. Lo he visto funcionar Desafortunadamente, el marco no permite específicamente la creación de un DataTemplate para System.Object; obtienes un error de tiempo de ejecución "El tipo 'DataTemplateKey' falló construcción. DataTemplate.DataType no puede ser tipo Object". –

+0

Tienes razón. Estaba pensando en Styles, que no son heredados automáticamente. Actualizando mi respuesta. Gracias. –

1

No estoy seguro acerca de reemplazar el valor por defecto DataTemplate, pero se puede usar un ValueConverter pasar ToString pantalla en el caso de ciertos tipos y una cadena vacía de lo contrario. Aquí hay algo de código (nótese que el imposible de TypeB bloque de texto tiene el convertidor en él para mostrar cómo se ve normalmente):

.xaml:

<Window x:Class="EmptyTemplate.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:loc="clr-namespace:EmptyTemplate" 
    Title="Window1" Height="300" Width="300"> 
    <Window.Resources> 
     <loc:AType x:Key="atype"/> 
     <loc:BType x:Key="btype"/> 
     <loc:TypeConverter x:Key="TypeConverter"/> 
    </Window.Resources> 
    <StackPanel> 
     <Button Content="{Binding Source={StaticResource atype}, Converter={StaticResource TypeConverter}}"/> 
     <Button Content="{Binding Source={StaticResource btype}, Converter={StaticResource TypeConverter}}"/> 
     <TextBlock Text="{Binding Source={StaticResource atype}, Converter={StaticResource TypeConverter}}"/> 
     <TextBlock Text="{Binding Source={StaticResource btype}}"/> 
    </StackPanel> 
</Window> 

.xaml.cs:

namespace EmptyTemplate 
{ 
    /// <summary> 
    /// Interaction logic for Window1.xaml 
    /// </summary> 
    public partial class Window1 : Window 
    { 
     public Window1() 
     { 
      InitializeComponent(); 
     } 
    } 

    public class AType { } 

    public class BType { } 

    public class TypeConverter : IValueConverter 
    { 
     public DataTemplate DefaultTemplate { get; set; } 

     #region IValueConverter Members 

     public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
     { 
      if (value.GetType() == typeof(AType)) 
      { 
       return value.ToString(); 
      } 
      return DefaultTemplate; 
     } 

     public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
     { 
      throw new NotImplementedException(); 
     } 

     #endregion 
    } 
} 
4

Si está utilizando el patrón MVVM y tiene una clase abstracta de la que derivan todas sus clases de ViewModel, puede usar esa clase en lugar de System.Object:

<Grid.Resources> 
    <DataTemplate DataType="{x:Type vm:VMBase}"> 
    </DataTemplate> 
</Grid.Resources> 
+2

Acabas de salvarme la vida. Bueno, no literalmente, por supuesto, pero esto es exactamente lo que estaba buscando – Firedragon

2

Usé Nullable, funcionó para mi situación.

<DataTemplate DataType="{x:Type sys:Nullable}"> 
<!-- Content --> 
</DataTemplate> 
0

Aquí un ejemplo de trabajo acerca de cómo hacer esto utilizando un selector (la mejor manera OMI):

public class EmptyDefaultDataTemplateSelector : DataTemplateSelector 
{ 
    public override DataTemplate SelectTemplate(object item, DependencyObject container) 
    { 
     if (item != null) 
     { 
      var dataTemplateKey = new DataTemplateKey(item.GetType()); 
      var dataTemplate = ((FrameworkElement) container).TryFindResource(dataTemplateKey); 
      if (dataTemplate != null) 
       return (DataTemplate) dataTemplate; 
     } 

     return new DataTemplate(); //null does not work 
    } 
} 
Cuestiones relacionadas