2010-12-10 8 views
6

Ich habe Probleme mit einem Konverter, den ich verwende, um zwischen einer Zeichenfolge und unserem Zeitformat zu konvertieren. Der Wandler selbst funktioniert gut und wird wie folgt implemeneted:mit IValueConverter mit aktuellen DataContext in Zwei-Wege-Bindung

[ValueConversion(typeof(string), typeof(SimpleTime))] 
    public class StringToSimpleTimeConverter : IValueConverter 
    { 
     public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
     { 
      // convert from string to SimpleTime and return it 
     } 
     public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
     { 
      // convert value from SimpleTime to string and return it 
     } 
    } 

Der XAML, die den Konverter verwendet beinhaltet den Wandler selbst in den UserControl.Resources wie folgt aus:

<converter:StringToSimpleTimeConverter x:Key="stringToSimpleTimeConverter"/> 

Wenn die Eigenschaft auftritt (I sind den Datagrid aus dem wpf Toolkit im Hintergrund verwenden) die Datatemplate für die Bearbeitung der Simple verwendet wird:

<DataTemplate x:Key="SimpleTimeEditingTemplate"> 
     <TextBox Text="{Binding, Converter={StaticResource stringToSimpleTimeConverter}, Mode=TwoWay}"/> 
</DataTemplate> 

Das Problem, das mir begegnet ist, ist, dass die con Verter muss in der Bindung einen Pfad angeben, wenn es ein Twoway-Konverter ist (und ich brauche es in beiden Richtungen), aber die Eigenschaft, die ich setzen möchte, ist bereits der aktuelle DataContext - welchen Pfad kann ich dann angeben?

Die einzige Problemumgehung, an die ich denken könnte, ist das Einführen einer Dummy-Eigenschaft in SimpleTime, die nur die aktuelle SimpleTime-Funktion aufruft oder sie festlegt.

public class SimpleTime 
{ 
    ... 
    public SimpleTime Clone 
    { 
     get { return new SimpleTime(_amount, _format); } 
     set { this._amount = value._amount; this._format = value._format; } 
    } 
} 

und binden an, dass man über

<TextBox Text="{Binding Clone, Converter={StaticResource stringToSimpleTimeConverter}, Mode=TwoWay}"/> 

, die gut funktioniert, aber nicht wirklich eine geeignete Lösung, vor allem, wenn i-Wandler für mehr mal brauchen ...

jede Hilfe ist geschätzt Prost, Manni

Antwort

5

Ich glaube, Sie es wie diese

umgehen kann
<TextBox Text="{Binding Path=DataContext, 
         RelativeSource={RelativeSource Self}, 
         Converter={StaticResource stringToSimpleTimeConverter}, 
         Mode=TwoWay}"/> 
+0

Ich habe einen ähnlichen Ansatz versucht, indem ich ein Eltern-Benutzer-Steuerelement für das Textfeld verwende und an seinen Datenkontext binde. Der IValueConverter wird korrekt aufgerufen, um die Zeichenfolge in simpletime und zurück zu konvertieren, um die Zeichenfolge im Steuerelement anzuzeigen, aber der Satz für die Eigenschaft simpletime in meiner Datenstruktur wird nie aufgerufen - weiß jemand, wie dies passieren kann? – manni

+0

@manni: Ich habe damit eine Test-App gemacht und für mich scheint es gut zu funktionieren. Es bindet sich an seinen eigenen DataContext, daher sehe ich keinen Grund dafür, dass es nicht funktioniert. Sind Sie sicher, dass Ihre ConvertBack-Methode nie aufgerufen wird? –

+1

danke für die Mühe. Ich denke, was ich sagen wollte, war nicht klar genug: meine Convertback und Convert-Methoden werden aufgerufen, wenn ich den Wert in der GUI ändere, das funktioniert gut. aber der Property Setter der Eigenschaft, die ich setze (die simpletime Eigenschaft), wird nicht aufgerufen (Breakpoint nicht ausgelöst). Ich werde jetzt einen Blick darauf werfen, danke sehr für Ihre Hilfe, ich schätze wirklich, dass – manni

0

Anstatt eine Dummy-Eigenschaft in Ihre Klasse einzuführen, warum erstellen Sie nicht eine Container-Klasse wie folgt:

public class Container 
{ 
    public Object DataItem { get; set; } 

    //... 
} 

und verwenden Sie es mögen:

<TextBox Text="{Binding DataItem, Converter={StaticResource stringToSimpleTimeConverter}, Mode=TwoWay}"/> 

Dies wird nicht korrupt/mutieren Ihre bestehenden Klasse und immer noch erlauben Sie, was Sie tun wollen, zu tun.

+0

gute Idee, aber nicht wirklich machbar für meine Datenstrukturen. Ich möchte nicht jede Eigenschaft in einen Container einfügen, und das übergeordnete List-Objekt ist direkt an das Datagrid gebunden, das für jede der Eigenschaften in der Klasse eine Spalte zum Anzeigen und Bearbeiten auswählt, die die Eigenschaft direkt als Datenkontext hat . – manni

+1

Ich denke, was Sie tun, ist das Setzen jeder Eigenschaft als ein 'DataContext' eines' Control' und binden sie mit '{Binding}' ohne Angabe eines Pfades. Wenn Sie das tun, ist es falsch. Sie sollten 'DataContext' eines übergeordneten Steuerelements festlegen, und alle untergeordneten Steuerelemente leiten es ab. Verwenden Sie Bindungen nur mit anderen Pfaden in untergeordneten Steuerelementen. – decyclone

+0

Ich dachte, dass die DataGridcolumns auf diese Weise funktionierten. Die Datatemplate, die ich für eine Gitterzelle im Datagrid verwende, um anzuzeigen oder zu bearbeiten, kann nicht den Datenkontext auf die komplette Struktur gesetzt haben, denn das würde bedeuten, dass er jetzt den Namen des Attributs hat, auf das er angewendet werden soll. Was ich will, ist, die Datamaplate auf den spezifischen Typ anzuwenden, ohne dessen Namen zu kennen, so dass mein Codebehind die Bindung für die Datagrid-Spalte festlegt und seine Datamplates zum Anzeigen und Editieren setzt. Das Datamaplate selbst wird auf mehr als einen Propertyname angewendet, abhängig von den Typen der Eigenschaften – manni

Verwandte Themen