none
Wie kann ich eine Eigenschaft beim ViewModel aus dem View ändern (MVVM) RRS feed

  • Allgemeine Diskussion

  • Wie kann ich mit einem Event in der View eine Eigenschaft des dahinterliegenden ViewModels ändern?

    Im unteren Beispiel sind die Test.xaml-Elemente ScatterViewItems auf der ScatterView des Hauptfensters.

    Ich würde jetzt gerne einen Event von einem Test-Element abfangen und z.B. den Text in der TestViewModel ändern. Dieser hat auch ein Get/Set Funktion für diesen Namen, welcher auch eine PropertyChange erzeugt.

    Ich hänge momentan an der Frage wie ich in der View auf das entsprechende ViewModel zugreifen kann.

    Window.xaml

    <Window x:Class="test.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="http://schemas.microsoft.com/surface/2008" xmlns:vm="clr-namespace:test" Title="test" Height="350" Width="525"> <Window.DataContext> <vm:MainWindowViewModel /> </Window.DataContext>
    <DataTemplate DataType="{x:Type vm:TestViewModel}">
            <vm:TestView />
        </DataTemplate> <Grid> <s:ScatterView x:Name="ScatterView" Background="White" ItemsSource="{Binding Items, UpdateSourceTrigger=PropertyChanged}" /> </Grid> </Window>

    test.xaml

    <UserControl x:Class="test.TestView"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
                 xmlns:s="http://schemas.microsoft.com/surface/2008"
                 mc:Ignorable="d" 
                 d:DesignHeight="300" d:DesignWidth="300">
            <Grid Background="Green" StylusSystemGesture="gh">
                <TextBlock Text="{Binding Name}"/>
        </Grid>
    </UserControl>

    TestView.xaml.cs

    public partial class TestView : UserControl
        {
            public TestView()
            {
                InitializeComponent();
            }
            private void gh(object sender, StylusSystemGestureEventArgs e)
            {
                
            }
        }



    • Bearbeitet egon56 Samstag, 17. November 2012 12:32
    • Typ geändert Ionut DumaModerator Donnerstag, 29. November 2012 16:32 Keine Rückmeldung des Fragenstellender
    Samstag, 17. November 2012 11:42

Alle Antworten

  • Hi rgon56,

    man kann z.b.  CommandBinding verwenden.

    Aus dem View kann man aber auch einfach Methoden des ViewModels aufrufen.

    MFG

    Björn

    Samstag, 17. November 2012 12:03
  • Wie kann er den die Methoden aufrufen?

    Also im oberen Beispiel geht in gh kein

     Name = "Neuer Name";
    Name ist eine Public String Name {...} Methode in TestViewModel


    • Bearbeitet egon56 Samstag, 17. November 2012 12:31
    Samstag, 17. November 2012 12:31
  • dein View kennt ja ein Instanz des ViewModel, dass heißt du kannst Methoden des ViewModels aufrufen.

    Dürfte so ähnlich aussehen.

    _myViewModel.MyMethode();

    b.z.w.

    _myViewModel.Name = "Neuer Name";

    Was in deinem Fall die beste Lösung ist kann ich natürlich nicht genau sagen.

    MFG

    Björn

    Samstag, 17. November 2012 14:00
  • Naja die Objekte werden dynamisch erzeugt. So dass ich in der View keinen Namen von der genauen ViewModel-Instanz habe.

    Samstag, 17. November 2012 14:06
  • Nach der dynamischen Erzeugung des ViewModels ist dieser doch bekannt. Wo ist da das Problem?
     
    --
    Viele Gruesse
    Peter
    Samstag, 17. November 2012 14:23
  • Die Elemente und quasi das dazugehörige ViewModel (der Elemente) werden im CodeBehind des Hauptfensters durch einen Event mit folgendem Code erzeugt:

    App.Messanger.NotifyColleagues("Test", new TestViewModel(e.GetPosition(this)));

    Im ViewModel des Hauptfensters werden sie dann auch gespeichert mit folgenden Methoden:

    void Subscriber()
            {
                App.Messanger.Register<TestViewModel>("Test",p => NewTest(p as TestViewModel));
            }
    
            void NewTest(TestViewModel spvm)
            {
                Items.Add(spvm);
            }
    
    public ObservableCollection<Item> Items
            {
                get
                {
                    if (_items == null)
                        _items = new ObservableCollection<Item>();
                    return _items;
                }
            }

    Auf diese Collection habe ich allerdings in der View von Test dann keinen Zugriff (Irgendwie)



    • Bearbeitet egon56 Samstag, 17. November 2012 16:43
    Samstag, 17. November 2012 16:34
  • Hi egon56,

    erstelle im View eine private Variable z.B. _myViewModel.

    Und ändere dann den Code.

    _myViewModel = new TestViewModel(e.GetPosition(this))
    App.Messanger.NotifyColleagues("Test", _myViewModel);

    Dann kannst du auf _myViewModel zugreifen.

    MFG

    Björn

    Samstag, 17. November 2012 17:08
  • Sowas mach ich ja auch im ViewModel des Hauptfensters. Aus irgendwelchen Gründen kann ich zwar dann nicht im CodeBehind der View von Test darauf zugreifen, aber sie wird angelegt.

    Aber selbst wenn ich das kann, muss ich ja immernoch wissen welches Test-ViewModel die aktuelle View betrachtet. Irgendwie muss die View doch eine Referenz zum ViewModel haben oder nicht?

    Sonntag, 18. November 2012 08:13
  • Ja die View muss eine Referenz auf eine Instanz des ViewModels haben.

    Und diese Instanz muss auch Irgendwo Erzeugt werden.

    Entweder vom View selber, von einer aufrufenden Klasse (die dann über ein Property oder den new Kontruktor das ViewModel an die View übergibt) oder einen IoC Container (z.B. vom MEF).

    Wie du dass jetzt Implementiert hast kann ich natürlich nicht sagen.

    MFG

    Björn

    Sonntag, 18. November 2012 11:58
  • Hallo egon56,

    Hat Dir die Antwort von Björn geholfen? Wenn ja - bitte markiere diese "als Antwort".

    Danke und Gruß,
    Ionut

    Montag, 26. November 2012 14:30
    Moderator
  • ****************************************************************************************************************
    Dieser Thread wurde mangels weiterer Beteiligung des Fragestellenden ohne bestätigte Lösung abgeschlossen.
    Neue Rückfragen oder Ergänzungen zu diesem Thread bleiben weiterhin möglich.
    ****************************************************************************************************************

    Donnerstag, 29. November 2012 16:31
    Moderator