16 Stimmen

Kann ich stark typisierte Bindungen in WPF/XAML erhalten?

Die Verwendung des MVVM -Pattern setzen Sie den DataContext auf ein bestimmtes ViewModel. Jetzt gibt es eine Möglichkeit, die XAML den Typ des DataContext zu sagen, so dass es meine Bindungen validieren wird?

Auf der Suche nach etwas wie die getippten Viewdata in ASP.NET MVC.

4voto

Andrey Shchekin Punkte 20287

Sie können jede einzelne Bindung auf eine stark typisierte Weise schreiben:

<TextBox Text="{Binding Path=(vm:Site.Contact).(vm:Contact.Name)}" />

Dies würde jedoch nicht die Tatsache, dass TextBox DataContext ist vom Typ ViewModel.Site (und ich denke, dies ist nicht möglich, aber ich kann falsch sein) zu validieren.

3voto

dustyburwell Punkte 5705

Nein, die aktuelle Spezifikation sieht keine starke Typisierung in Xaml vor. Ich glaube, dass mit .Net 4.0, Xaml sollte die Fähigkeit für Generika zu sehen. Damit sollte es meiner Meinung nach viel einfacher sein, starke Typisierung in Xaml zu haben.

3voto

markti Punkte 2783

Nein. FrameworkElement.DatatContext ist die Abhängigkeitseigenschaft, die die Datenbindung ermöglicht, vom Typ object .

Wie bereits von anderen erwähnt, können Sie den erwarteten Typ einer DataContext für eine spezielle Vorlage namens DataTemplate . Viele Kontrollen wie z. B. ItemsControl , ControlControl ermöglichen den Zugriff auf DataTemplates, damit Sie die Erwartungen der visuellen Darstellung an den Typ des DataContextes festlegen können.

Bryan hat recht, er hat seinen Code nicht getestet.

Die korrekte Anwendung eines typisierten DataTemplates sieht wie folgt aus:

<Window>
    <Window.Resources>
        <DataTemplate x:Key="TypedTemplate" DataType="{x:Type myViewModel}">
        ...
        </DataTemplate>
    </Window.Resources>
    <ContentControl Content="{Binding}" ContentTemplate="{StaticResource TypedTemplate}" />
</Window>

ContentPresenter erbt direkt von FrameworkElement und verfügt nicht über eine Template-Eigenschaft. Darüber hinaus bezieht sich die Eigenschaft Template in der Regel auf Control.Template vom Typ ControlTemplate, was etwas völlig anderes ist als ein DataTemplate.

Ich glaube, Bryan dachte an die ContentControl die eine der beiden Arten von Root-Kontrollen ist (die andere ist ItemsControl ). ContentControl erbt in der Tat von Control. Daher können wir die Eigenschaft Template angeben, wenn wir dies wünschen.

<Window>
   <Window.Resources>
      <DataTemplate x:Key="TypedTemplate" DataType="{x:Type myViewModel}">
      ...
      </DataTemplate>
      <ControlTemplate x:Key="ControlSkin" TargetType="{x:Type ContentControl}">
      ...
      </ControlTemplate>
   </Window.Resources>
   <ContentControl Content="{Binding}" ContentTemplate="{StaticResource TypedTemplate}" Template="{StaticResource ControlSkin}" />
</Window>

2voto

LozH Punkte 21

Ich persönlich deklariere einen statischen PropertyPath für jede Eigenschaft in meinem Viewmodel und referenziere diesen mit x:static als Bindungspfad - z.B.

public class MyViewModel
{
  public static PropertyPath MyPropertyPath = new PropertyPath("MyProperty");
  public bool MyProperty{get; set;}
}

xaml : {Binding Path={x:Static local:MyViewModel.MyPropertyPath}}

Auf diese Weise werden alle meine Bindungen bei der Erstellung validiert.

1voto

Bryan Anderson Punkte 15626

Versuchen Sie dies:

<Window>
    <Window.Resources>
        <DataTemplate x:Key="TypedTemplate" DataType="{x:Type myViewModel}">
            ...
        </DataTemplate>
    </Window.Resources>

    <ContentPresenter Content="{Binding}" Template="{StaticResource TypedTemplate}" />
</Window>

Ich habe diesen Code nicht getestet, aber er sollte Ihnen einen Eindruck vermitteln. Der Content Presenter zeigt den aktuellen DataContext an, der das DataTemplate verwendet. Dieses ist im Compiler nicht stark typisiert, wird aber sofort beim Laden einen Laufzeitfehler auslösen (in der InitializeComponent des Fensters). Sie sollten in der Lage sein, dies bei Ihren Tests leicht zu erkennen, wenn etwas nicht funktioniert.

0 Stimmen

.Net 3.5 hat keine DataTemplate.TargetType Eigenschaft

0 Stimmen

@Brian Sie haben Recht, es ist DataType. Ich sagte, es sei ungetestet. Ich habe die Antwort aktualisiert, um den Fehler zu beheben.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X