2012-08-02 10 views
8

W zasadzie opracowałem zgrabny sposób wiązania radiobuttons niemal do wszystkiego:Błąd podczas wiązania przy użyciu rozszerzeń znaczników: Nieznany Obiekt napotkanych podczas analizowania Markup Extension

/// <summary>Converts an value to 'true' if it matches the 'To' property.</summary> 
/// <example> 
/// <RadioButton IsChecked="{Binding VersionString, Converter={local:TrueWhenEqual To='1.0'}}"/> 
/// </example> 
public class TrueWhenEqual : MarkupExtension, IValueConverter 
{ 
    public override object ProvideValue(IServiceProvider serviceProvider) 
    { 
     return this; 
    } 

    public object To { get; set; } 

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     return object.Equals(value, To); 
    } 
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     if ((bool)value) return To; 
     throw new NotSupportedException(); 
    } 
} 

Na przykład, można to wykorzystać, aby związać radiobuttons do właściwości String następująco (jest to znany błąd, który trzeba użyć unikatowy groupName każdego RadioButton):

<RadioButton GroupName="G1" Content="Cat" 
    IsChecked="{Binding Animal, Converter={local:TrueWhenEqual To='CAT'}}"/> 
<RadioButton GroupName="G2" Content="Dog" 
    IsChecked="{Binding Animal, Converter={local:TrueWhenEqual To='DOG'}}"/> 
<RadioButton GroupName="G3" Content="Horse" 
    IsChecked="{Binding Animal, Converter={local:TrueWhenEqual To='HORSE'}}"/> 

teraz chciałbym użyć public static readonly obiektów zwanych Filter1 i Filter2 jako wartości mój Rad ioButtons. Tak próbowałem:

<RadioButton GroupName="F1" Content="Filter Number One" 
    IsChecked="{Binding Filter, Converter={local:TrueWhenEqual To='{x:Static local:ViewModelClass.Filter1}'}}"/> 
<RadioButton GroupName="F2" Content="Filter Number Two" 
    IsChecked="{Binding Filter, Converter={local:TrueWhenEqual To='{x:Static local:ViewModelClass.Filter2}'}}"/> 

Ale to daje mi błąd:

Unknown property 'To' for type 'MS.Internal.Markup.MarkupExtensionParser+UnknownMarkupExtension' encountered while parsing a Markup Extension.

Błąd nadal występuje jeśli usunąć cudzysłowy. Co ja robię źle?

Odpowiedz

9

To błąd, który może wystąpić w zagnieżdżonych MarkupExtensions. Spróbuj umieścić niestandardową znacznik w osobnej bibliotece DLL/projekcie lub użyj składni elementu właściwości.

+1

Drugi związek ma poprawną odpowiedź (przez co mam na myśli łatwą odpowiedź). Po prostu muszę zdefiniować konstruktora 'public TrueWhenEqual (object to) {To = to; } ', a następnie wywołaj konwerter za pomocą' Konwerter = {local: TrueWhenEqual {x: Statyczny lokalny: ViewModelClass.Filter1}}} ' – Qwertie

5

WPF nie obsługuje rozszerzeń zagnieżdżonych znaczników zbyt dobrze. Aby temu zaradzić, możesz użyć rozszerzenia znaczników jako elementu. To trochę niezdarny i trudniejsze do odczytania, ale to działa:

<RadioButton GroupName="F1" Content="Filter Number One"> 
    <RadioButton.IsChecked> 
     <Binding Path="Filter"> 
      <Binding.Converter> 
       <local:TrueWhenEqual To={x:Static local:ViewModelClass.Filter1} /> 
      </Binding.Converter> 
     </Binding> 
    </RadioButton.IsChecked> 
</RadioButton> 

Innym sposobem byłoby zadeklarować konwertera i używać go jako statyczny zasób:

<Window.Resources> 
    <local:TrueWhenEqual To={x:Static local:ViewModelClass.Filter1} x:Key="myConverter" /> 
</Window.Resources> 

<RadioButton GroupName="F1" Content="Filter Number One" 
      IsChecked="{Binding Filter, Converter={StaticResource myConverter}}" /> 
+0

Clunky, ale działa. Właściwie to nie * działa *, ale kompiluje (podejrzewam, że następny problem dotyczy mojej struktury MVVM, UpdateControls). – Qwertie

+0

Potwierdzone, to rozwiązanie działa bez mojego środowiska MVVM. Jednak zdefiniowanie konstruktora na MarkupExtension jest znacznie lepszym rozwiązaniem. Następnie zmieniłem nazwę na "TrueWhenEqualTo", który brzmi bardziej naturalnie: "IsChecked =" {Filtr wiążący, konwerter = {local: TrueWhenEqualTo {x: Statyczny lokalny: ViewModelClass.Filter1}}} "'. Oczywiście "naturalnie" jest terminem względnym; XAML nadal wygląda jak bełkot niewtajemniczonych; ^) – Qwertie

Powiązane problemy