2012-08-02 8 views
8

In linea di principio, ho sviluppato un modo pulito per legarsi RadioButtons a quasi tutto:errore durante l'associazione con le estensioni di markup: Proprietà sconosciuta incontrata durante l'analisi un'estensione di markup

/// <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(); 
    } 
} 

Ad esempio, è possibile utilizzare questo per legare RadioButtons a una proprietà di stringa come segue (si tratta di un bug noto che è necessario utilizzare un GroupName unico per ogni 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'}}"/> 

Ora, vorrei utilizzare public static readonly oggetti chiamati Filter1 e Filter2 come i valori di il mio Rad ioButtons. Così ho provato:

<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}'}}"/> 

Ma questo mi dà un errore:

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

L'errore si verifica ancora se rimuovere le virgolette. Che cosa sto facendo di sbagliato?

risposta

9

È un errore che si può verificare con MarkupExtensions nidificati. Prova a inserire il markup personalizzato in una DLL/progetto separata o usa la sintassi dell'elemento proprietà.

+1

Il secondo collegamento è la risposta corretta (con il quale intendo, la risposta facile). Devo semplicemente definire un costruttore 'public TrueWhenEqual (object to) {To = to; } 'e quindi invoca il convertitore con' Converter = {local: TrueWhenEqual {x: Statico locale: ViewModelClass.Filter1}}} ' – Qwertie

5

WPF non gestisce le estensioni di markup nidificati troppo bene. Per ovviare a questo, puoi usare la tua estensione di markup come elemento. E 'un po' goffo e difficile da leggere, ma funziona:

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

Un altro modo sarebbe quello di dichiarare il vostro convertitore e usarlo come una risorsa statica:

<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, ma funziona. Beh, in realtà non funziona *, ma lo fa (sospetto che il prossimo problema sia nel mio framework MVVM, UpdateControls). – Qwertie

+0

Confermato, questa soluzione funziona senza il mio framework MVVM. Definire un costruttore su MarkupExtension è comunque una soluzione molto migliore. Quindi l'ho rinominato in 'TrueWhenEqualTo' che legge più naturalmente:' IsChecked = "{Filtro binding, Convertitore = {locale: TrueWhenEqualTo {x: Locale statico: ViewModelClass.Filter1}}}" '. Naturalmente, "naturalmente" è un termine relativo; XAML sembra ancora senza senso per i non iniziati; ^) – Qwertie

Problemi correlati