2009-10-30 14 views
34

¿Hay alguna forma de hacer una comparación en el tipo de objeto para un desencadenante?Disparador WPF basado en el tipo de objeto

<DataTrigger Binding="{Binding SelectedItem}" Value="SelectedItem's Type"> 
</DataTrigger> 

Antecedentes: Tengo una barra de herramientas y quiero ocultar el botón de función de lo que se establece subclase actualmente al objeto de elemento seleccionado.

Gracias

Respuesta

29

Por qué no utilizar un convertidor que toma un objeto y devuelve una cadena del tipo de objeto?

Binding="{Binding SelectedItem, Converter={StaticResource ObjectToTypeString}}"

y definir el convertidor como:

public class ObjectToTypeStringConverter : IValueConverter 
{ 
    public object Convert(
    object value, Type targetType, 
    object parameter, System.Globalization.CultureInfo culture) 
    { 
     return value.GetType().Name;    
    } 

    public object ConvertBack(
    object value, Type targetType, 
    object parameter, System.Globalization.CultureInfo culture) 
    { 
     // I don't think you'll need this 
     throw new Exception("Can't convert back"); 
    } 
} 

Tendrá que declarar el recurso estático en algún lugar de su xaml:

<Window.Resources> 
    <convs:ObjectToTypeStringConverter x:Key="ObjectToTypeString" /> 
</Window.Resources> 

donde "Convs en el presente caso es el espacio de nombres de donde está el convertidor.

Espero que esto ayude.

+10

+1 para la idea general, sin embargo, el convertidor debería devolver el objeto Type en lugar de su nombre ... –

+2

¿Funcionaría eso? ¿No estaría el tiempo de ejecución comparando algo de tipo String a algo de tipo Type? Sé que maneja la conversión/comparación de la mayoría de los tipos de valor, pero no está familiarizado con la forma en que maneja otras comparaciones de tipos. – AndyG

+5

Sí, funcionaría, solo tiene que usar la extensión de marcado {x: Type} en el valor DataTrigger. –

4

Usar un convertidor según lo sugerido por AndyG es una buena opción. Alternativamente, también puede usar un DataTemplate diferente para cada tipo de objetivo. WPF seleccionará automáticamente el DataTemplate que coincida con el tipo de objeto

+0

Pero también afectará a cada subelemento de ese tipo de datos – Staeff

42

Esto se basa en la respuesta de @ AndyG, pero es un poco más seguro porque está fuertemente tipado.

Implementar un llamado IValueConverter DataTypeConverter, que acepta un objeto y devuelve su tipo (como System.Type):

public class DataTypeConverter:IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, 
     CultureInfo culture) 
    { 
     return value.GetType(); 
    } 

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

Cambiar la DataTrigger utilizar el convertidor, y establecer el valor de la Tipo:

<DataTrigger Binding="{Binding SelectedItem, 
     Converter={StaticResource DataTypeConverter}}" 
     Value="{x:Type local:MyType}"> 
... 
</DataTrigger> 

DataTypeConverter Declare en los recursos:

<UserControl.Resources> 
    <v:DataTypeConverter x:Key="DataTypeConverter"></v:DataTypeConverter> 
</UserControl.Resources> 
+1

Esto no funciona para mí. Obtengo una XamlParseException si trato de usar una extensión de marca en DataTrigger.Value, así que acabo de utilizar el método de comparación de cadenas en su lugar. Vea aquí: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/14cbdb99-fd33-4ad0-8b1b-a0139c7fbf95/ – RobJohnson

+3

Mejor compruebe si el valor es nulo antes de intentar GetType(). valor de retorno! = nulo? value.GetType(): null; – Viv

+0

'Binding =" {Binding SelectedItem} "Converter = {StaticResource DataTypeConverter}}" 'debe ser' Binding = "{Enlace SelectedItem, Converter = {StaticResource DataTypeConverter}}" ' – Firo

3

No es un disparador, pero esto funcionó para mí. (El disparador-enfoque no hizo lo que no puede crear una casilla de verificación para una cadena Esto es más o menos Thomas Levesque's suggestion.)

usando:

xmlns:mscorlib="clr-namespace:System;assembly=mscorlib" 

una casilla de verificación o cuadro de texto en función del tipo:

<ContentPresenter Content="{TemplateBinding SelectedItem}"> 
     <ContentPresenter.Resources> 
       <DataTemplate DataType="{x:Type mscorlib:Boolean}"> 
        <CheckBox Height="25" Width="25" HorizontalAlignment="Left" IsChecked="{Binding Path=.}"/> 
       </DataTemplate> 
        <DataTemplate DataType="{x:Type mscorlib:String}"> 
        <TextBox Height="25" Width="200" HorizontalAlignment="Left" Text="{Binding Path=.}"/> 
       </DataTemplate> 
     </ContentPresenter.Resources> 
</ContentPresenter> 

Nota: para la solución de Greg Sansom que o bien tiene que devolver el tipo como cadena o utilizar mscorlib que el anterior

Cuestiones relacionadas