2014-05-17 15 views
9

Ograniczenie to pytanie do minimum, należy rozważyć tę klasę MarkupExtension ...konstruktor domyślny parametrów w deklaracji MarkupExtension

public class ProblemStatement : MarkupExtension 
{ 
    private readonly string _first; 
    private readonly string _second; 
    public ProblemStatement(string first, string second) 
    { 
     _first = first; 
     _second = second; 
    } 
    public override object ProvideValue(IServiceProvider serviceProvider) 
    { 
     return this; 
    } 
    public override string ToString() 
    { 
     return _first + _second; 
    } 
} 

Kiedy ten Xaml deklaruje ...

<Grid> 
    <TextBlock Name="TextBlock1" Tag="{so:ProblemStatement 'hello', 'world'}"/> 
    <TextBlock Text="{Binding ElementName=TextBlock1, Path=Tag}"/> 
</Grid> 

... ty zobacz "helloworld" w TextBlock zgodnie z oczekiwaniami. Wszystko dobrze w tym momencie.

Ale zmieniając parametr konstruktora do tego ...

public ProblemStatement(string first, string second = "nothing") 

... i odpowiedni Xaml do tego ...

<Grid> 
     <TextBlock Name="TextBlock1" Tag="{so:ProblemStatement 'hello'}"/> 
     <TextBlock Text="{Binding ElementName=TextBlock1, Path=Tag}"/> 
    </Grid> 

otrzymany komunikat o błędzie ...

No constructor for type 'ProblemStatement' has 1 parameters. 

Istnieje obejście, które ma połączyć projektanta, dodając to oświadczenie do klasy ...

public ProblemStatement(string first) : this(first, "not provided") { } 

a to pokaże 'hellonot warunkiem' w TextBlock. Zmienia to jednak również semantykę rozszerzenia MarkupExtension i nie jest pożądane w przypadku większego "rzeczywistego" przypadku. Również złożoność przeciążania rośnie dramatycznie, gdy używane są bardziej złożone typy lub argumenty konstruktora są typu "dynamicznego". Na przykład użycie nowych atrybutów "Informacje o dzwoniącym" jest całkowicie zablokowane.

Pytanie brzmi: jak zadeklarować Xaml, aby parser Xaml przyjął domyślny argument konstruktora?

Odpowiedz

8

Spróbuj tego:

public string Optional{ get; set; } = "DefaultValue"; 

    private readonly string _mandatory; 

    public ProblemStatement(string mandatory) 
    { 
     _mandatory = mandatory; 
    } 

Zastosowanie:

<TextBlock Name="TextBlock1" Tag="{local:ProblemStatement 'hello', Optional=NotDefault}"/> 

alternatywa:

<TextBlock Name="TextBlock1" Tag="{local:ProblemStatement 'hello'}"/> 

Wynik:

  • No XAML parsin g błędy
  • Nie trzeba przeciążać konstruktora dla parametrów opcjonalnych
  • Obowiązkowe parametry są parametrami konstruktora.
  • Parametrami opcjonalnymi są właściwości.
+0

Jakie korzyści daje w tym przypadku "ConstructorArgumentAttribute", ponieważ właściwość o nazwie "Opcjonalny" w rzeczywistości nie jest argumentem konstruktora? Myślałem, że 'ConstructorArgumentAttribute' ma na celu lepsze informowanie serialu XAML o relacji między faktycznym argumentem konstruktora a właściwością. –

+0

@AdamCaviness Brak. W tym czasie miałem złe wrażenie na tym atrybucie. odpowiedź odpowiednio edytowana. –

Powiązane problemy