2 Stimmen

WPF wie man zwei beobachtbare Sammlungen von verschiedenen, aber verwandten Typen mit einem Wertkonverter binden?

Ich habe ein benutzerdefiniertes Steuerelement mit einer beobachtbaren Sammlung (DP), die einen bestimmten Objekttyp enthält. Ich möchte es an eine andere beobachtbare Sammlung mit Objekten eines anderen Typs in meiner VM binden. Wie kann ich das tun?

Sollte ich so etwas überhaupt tun?

Bearbeiten. Natürlich sollte die Bindung funktionieren, wenn Elemente in den Sammlungen auf beiden Seiten geändert werden.

3voto

Snowbear Punkte 16623

Meleak ist richtig, Sie sollten eine Sammlung irgendwie in eine andere umwandeln und sie synchronisieren. Hier ist, wie ich es das letzte Mal tat:

Ansicht (ich habe sie MyControl unten) hat die Eigenschaft Items vom Typ IEnumerable<Target>
DataContext hat die Eigenschaft Items vom Typ IEnumerable<Source>

class CollectionsConverter : IValueConverter
{
    public object Convert(object value, ...)
    {
        var source = (ObservableCollection<Source>)value;
        var target = new ObservableCollection<Target>(source.Select(/* Convert items somehow /);
        // subscribe to both target's and source's 'CollectionChanged' events
        // and propagate them back and forth to another collection.
        // Propagated events should have converted items of course

        return target;
    }
    ...
}

Dann in XAML:

<MyControl Items="{Binding Items, Converter=CollectionsConverter}" />

Was die Konvertierung der einzelnen Elemente betrifft, so kann es sich entweder um generischen Code handeln, der dynamisch bestimmt, wie die Konvertierung erfolgen soll Source a Target und umgekehrt, oder es sollte ein Code sein, der genau weiß, welche Typen er konvertieren wird und wie er sie konvertieren kann.

0voto

Ana Betts Punkte 72423

ValueConverters funktionieren nicht so, wie Sie es beschreiben, Sie müssen eine neue Sammlung von Hand erstellen.

Das beantwortet zwar nicht direkt Ihre Frage, aber in ReactiveUI (http://www.reactiveui.net) ist dieses Szenario recht einfach:

var derivedColl = someCollection.CreateDerivedCollection(x => new SomeOtherClass(x));

-1voto

RockWorld Punkte 1302

Verwenden Sie Ihre eigene Konverterklasse, die IValueConverter implementiert

    public class ObserverTypeConverter:IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            //return your dependency type from here     
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            //return your view model type from here, this will get fired if your binding is two way
        }
    }

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