2012-08-02 4 views
8

Grundsätzlich habe ich eine nette Art und Weise entwickelt, Radiobuttons, um fast alles zu binden:Fehler beim Markup Erweiterung Bindung mit: Unbekannte Eigenschaft festgestellt, während eine Markup-Erweiterung Parsen

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

Zum Beispiel können Sie diese verwenden, Radiobuttons zu binden wie folgt zu einem String-Eigenschaft (es ein bekannter Fehler ist, dass Sie einen eindeutigen Gruppenname für jede RadioButton- verwenden müssen):

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

Jetzt würde ich public static readonly Objekte Filter1 und Filter2 als Werte genannt verwenden möchten von mein Rad ioButtons. Also habe ich versucht:

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

Aber das gibt mir eine Fehlermeldung:

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

Der Fehler tritt immer noch, wenn ich die Anführungszeichen zu entfernen. Was mache ich falsch?

Antwort

9

Es ist ein Fehler, der bei verschachtelten MarkupExtensions auftreten kann. Versuchen Sie, Ihr benutzerdefiniertes Markup in eine separate DLL/ein anderes Projekt zu laden oder verwenden Sie die Eigenschaftselement-Syntax.

+1

Der zweite Link, um die richtige Antwort hat (womit ich meine, die einfache Antwort). Ich muss einfach einen Konstruktor definieren 'public TrueWhenEqual (object to) {To = to; } 'und dann den Konverter mit' Converter = {local: TrueWhenEqual {x: Static lokal: ViewModelClass.Filter1}}}} ' – Qwertie

5

WPF behandelt nicht verschachtelte Markup zu gut Erweiterungen. Um dies zu umgehen, können Sie Ihre Markup-Erweiterung als Element verwenden. Es ist ein bisschen ungeschickt und schwieriger zu lesen, aber es funktioniert:

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

Ein anderer Weg wäre, um Ihre Konverter zu erklären und es als eine statische Ressource zu verwenden:

<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, aber es funktioniert. Nun, eigentlich funktioniert es nicht, aber es kompiliert (ich vermute, das nächste Problem ist in meinem MVVM-Framework, UpdateControls). – Qwertie

+0

Bestätigt, diese Lösung funktioniert ohne mein MVVM-Framework. Das Definieren eines Konstruktors für die MarkupExtension ist jedoch eine viel bessere Lösung. Dann habe ich es in 'TrueWhenEqualTo' umbenannt, das natürlich liest:' IsChecked = "{Binding Filter, Converter = {local: TrueWhenEqualTo {x: Statisch lokal: ViewModelClass.Filter1}}}". Natürlich ist "natürlich" ein relativer Begriff; XAML sieht immer noch wie Kauderwelsch für Uneingeweihte aus; ^) – Qwertie

Verwandte Themen