2009-10-30 14 views
34

Czy istnieje sposób na porównanie typu obiektu dla wyzwalacza?Wyzwalacz WPF oparty na obiekcie Typ

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

Tło: Mam pasek i chcę ukryć przycisk użytkownika w zależności od podklasy jest aktualnie ustawiony na wybranym obiekcie poz.

Dzięki

Odpowiedz

29

Dlaczego nie wystarczy użyć konwerter, który przyjmuje obiekt i zwraca ciąg znaków typu obiektu?

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

konwertera i zdefiniować jako:

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"); 
    } 
} 

Musisz zadeklarować zasobu statyczną gdzieś w XAML:

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

Gdzie convs 'w tym przypadku jest przestrzenią nazw konwertera.

Mam nadzieję, że to pomoże.

+10

+1 dla ogólnej idei, jednak konwerter powinien zwracać obiekt typu, a nie jego nazwę ... –

+2

Czy to działa? Czy środowisko wykonawcze nie porównywałoby czegoś typu String z typem Type? Wiem, że obsługuje konwersję/porównywanie większości typów wartości, ale nie zna sposobu, w jaki obsługuje inne porównania typów. – AndyG

+5

Tak, to by działało, po prostu musisz użyć rozszerzenia znaczników {x: Type} w wartości DataTrigger. –

4

Korzystanie z konwertera zgodnie z sugestią AndyG jest dobrym rozwiązaniem. Alternatywnie można również użyć innego DataTemplate dla każdego typu celu. WPF automatycznie wybierze DataTemplate, który pasuje do typu obiektu

+0

Ale wpłynie to również na każdy podelement tego typu danych. – Staeff

42

Jest to oparte na odpowiedzi @ AndyG, ale jest nieco bezpieczniejsze, ponieważ jest mocno wpisane.

Wdrożenie IValueConverter nazwie DataTypeConverter, który akceptuje obiekt i zwraca jego typu (jako 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(); 
    } 
} 

Zmień DataTrigger używać przetwornicy, i ustawić wartość na typ:

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

Declare DataTypeConverter w zasobach:

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

To nie działa dla mnie. Dostaję wyjątek XamlParseException, jeśli spróbuję użyć rozszerzenia markdown w DataTrigger.Value, więc użyłem właśnie metody porównywania ciągów znaków. Zobacz tutaj: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/14cbdb99-fd33-4ad0-8b1b-a0139c7fbf95/ – RobJohnson

+3

Lepiej sprawdź, czy wartość jest zerowa przed próbą GetType(). zwracana wartość! = null? value.GetType(): null; – Viv

+0

'Binding =" {Binding SelectedItem} "Konwerter = {StaticResource DataTypeConverter}}" 'powinno być' Binding = "{Binding SelectedItem, Converter = {StaticResource DataTypeConverter}}" ' – Firo

3

Nie był to spust, ale to działało dla mnie. (Spust-podejście nie zrobił, ponieważ nie można utworzyć pole wyboru ciąg ten jest dość dużo Thomas Levesque's suggestion).

używając:

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

CheckBox lub TextBox w zależności od typu:

<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> 

Uwaga: do sporządzania roztworu Greg Sansom'a trzeba albo dostał się do powrotu typem String lub użyj mscorlib jak wyżej

Powiązane problemy