2010-11-18 14 views
0

Ein anderes Problem hat mich in letzter Zeit nervig gemacht, und ich bin ziemlich sicher, dass es meine fehlenden WPF/MVVM-Fähigkeiten sind, die mich davon abhalten, das Offensichtliche zu sehen. Ich bin mir sicher, dass die Lösung einfach ist, aber ich bin nicht sicher, wie ich sie umsetzen soll.Anzeigen von Daten in verschiedenen Ansichtsmodellen, ohne Modelldaten zu ändern

Ich entwickle in WPF/C# und ich verwende das MVVM Designmuster.

Der Einfachheit halber koche ich die Frage bis zu den grundlegendsten Komponenten.

Das Szenario:

Ich habe ein Modell, nur eine ganze Zahl enthält.

Ich habe ein übergeordnetes ViewModel, das diese ganze Zahl anzeigt.

Ich habe zwei untergeordnete Ansichtsmodelle, die im übergeordneten Ansichtsmodell enthalten sind und beide diese Ganzzahl anzeigen. Auf einem der Viewmodel habe ich einen Command, der den Wert der Ganzzahl um 1 erhöht. Der Wert wird im Model geändert, was die INotifyPropertyChanged implementiert und somit das zweite ViewModel auf die Änderung aufmerksam macht, damit es entsprechend aktualisiert werden kann.

Bis jetzt funktioniert alles gut.

Allerdings bin ich an einer neuen Funktion interessiert, und ich kann es nicht zum Laufen bringen. Sagen wir, dass ich in meinem zweiten Viewmodel die ganze Zahl anzeigen möchte, aber ich möchte die Darstellung der Daten transformieren. Dies sollte jedoch geschehen, ohne die Daten im Modell zu ändern. Sollten sich die Daten im Modell ändern, ändern sich die transformierten Daten entsprechend.

Als Beispiel nehmen wir an, dass die Ganzzahl 5 ist. Auf dem zweiten Viewmodell möchte ich die Ganzzahl + 2 anzeigen, also 7. Dann werden die Daten vom ersten Viewmodel auf 6 geändert, was die Eigenschaft bedeutet auf dem zweiten Viewmodel ändert sich automatisch zu 8.

Wie ist das implementiert?

Einige codepieces, zu veranschaulichen, was das System wie bisher aussieht:

Das Modell:

public DataModel() 
{ 
    data = new Data(); 

    data.Value = 2; 
} 

public Data data { get; set; } 

und die Datenklasse:

public class Data : INotifyPropertyChanged 
{ 
    private int m_Value; 
    public int Value 
    { 
     get { return m_Value; } 
     set 
     { 
      if (m_Value != value) 
      { 
       m_Value = value; 
       OnPropertyChanged("Value"); 
      } 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    protected virtual void OnPropertyChanged(string propertyName) 
    { 

     PropertyChangedEventHandler handler = this.PropertyChanged; 
     if (handler != null) 
     { 
      var e = new PropertyChangedEventArgs(propertyName); 
      handler(this, e); 
     } 
    } 

Die mainviewmodel

public class MainViewModel : ViewModelBase 
{ 
    readonly DataModel _dataModel; 

    public MainViewModel() 
    { 
     _dataModel = new DataModel(); 

     ViewModel1 = new 1ViewModel(this); 
     ViewModel2 = new 2ViewModel(this); 
    } 


    public 1ViewModel ViewModel1 { get; set; } 

    public 2ViewModel ViewModel2 { get; set; } 

    public Data Data 
    { 
     get { return _dataModel.data; } 

    } 



} 

Und hier ist die Art, wie die ChildViewmodel sich auf die Objektdaten binden

public class 1ViewModel : ViewModelBase 
{ 

    private MainViewModel _mainViewModel; 

    public 1ViewModel(MainViewModel mainViewModel) 
    { 
     _mainViewModel = mainViewModel; 

    } 

    public Data Number 
    { 
     get { return _mainViewModel.data; } 

    } 

}

Und auf der view1, habe ich die Nummer Eigenschaft wie diese

<TextBlock Text="{Binding Path=Number.Value}" /> 

wieder gebunden, ich will in der Lage sein, eine zweite Eigenschaft auf dem Ansichtsmodell zu erstellen, die die transformierten Daten basierend auf, aber ohne die ursprünglichen Daten zu ändern, und welche Aktualisierungen zusammen mit den Daten, die aktualisiert werden, anzeigt. Vorzugsweise sollte es eine Art Konverter-Methode sein, die die Daten in die neuen Daten umwandelt.

Ich hoffe, Sie können helfen.

Antwort

1

Das ViewModel sollte die Daten für die Anzeige bereithalten, aber nicht wissen, wie sie angezeigt werden. Wenn Sie die Art und Weise ändern möchten, in der die Daten in Ihrer Ansicht angezeigt werden, verwenden Sie hierfür Converter. Auf diese Weise können Sie dasselbe ViewModel für mehrere Ansichten verwenden und unterschiedliche Darstellungen aufweisen.

Außerdem ist es nicht unbedingt notwendig, ein ViewModel in ein ViewModel zu integrieren. Ein ViewModel hat im Allgemeinen eine verknüpfte Ansicht. Wenn Sie keine Ansicht für das ViewModel haben, behandeln Sie die Daten als typische Klassen und fahren Sie mit Ihrem einzelnen ViewModel fort.

+0

Danke, ich werde das sofort untersuchen. Und der Grund für mich, mehr View-Modelle zu verwenden, ist, dass das Haupt-View-Model eine Tab-Control hat und jedes Sub-View-Model ein anderes Tab ist. Sie haben alle die gleiche Datenquelle, aber sie zeigen die Daten unterschiedlich an. – Sagi1981

0

eine IValueConverter Verwendung:

public class AddConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     return (int)value + (int)parameter; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     return (int)value - (int)parameter;    
    } 
} 

Und in XAML, fügen Sie die Ressource:

und aktualisieren Sie Ihre Bindung:

ich hier eine Converter verwendet, aber Sie können Hardcode den Wert wenn gewünscht. Möglicherweise möchten Sie auch einige Überprüfungen zu Ihrem Konverter hinzufügen, da es eine Ausnahme auslöst, wenn die Typen nicht korrekt sind.

Verwandte Themen