2016-11-24 2 views
2

Ich versuchte auf der Suche nach Antworten auf ähnliche Fragen, aber ich konnte nichts finden, was zu dieser Situation passt.Wie aktualisieren WPF UserControl Eigenschaft in StatusBarItem in MainWindow Formular ein anderes UserControl mit beiden unterschiedlichen DataContexts?

Ich habe ein Hauptfenster, die so etwas wie dies (einige Teile weggelassen) aussieht:

<Window x:Class="test.MainWindow" 
    xmlns:local="clr-namespace:test" 
    xmlns:Views="clr-namespace:test.Views"> 
    <Grid> 
     <DockPanel> 
      <StatusBar> 
       <StatusBarItem> 
        <Views:ProfileView /> 
       </StatusBarItem> 
       <Separator /> 
       <StatusBarItem> 
        <Views:StatusView /> 
       </StatusBarItem> 
      </StatusBar> 
     </DockPanel> 
    </Grid> 
</Window> 

mit Code-Behind:

using System.Windows; 

namespace test 
{ 
    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 
     } 

     // some stuff done here 
    } 
} 

und zwei Usercontrol:

<UserControl x:Class="test.Views.StatusView" 
    xmlns:local="clr-namespace:test.Views" 
    xmlns:ViewModels="clr-namespace:test.ViewModels"> 
    <UserControl.DataContext> 
     <ViewModels:StatusViewModel/> 
    </UserControl.DataContext> 
    <Grid> 
     <Border> 
      <TextBlock Text="{Binding Status}" /> 
     </Border> 
    </Grid> 
</UserControl> 

und:

<UserControl x:Class="test.Views.ProfileView" 
    xmlns:local="clr-namespace:test.Views" 
    xmlns:ViewModels="clr-namespace:test.ViewModels" MouseEnter="UserControl_MouseEnter" MouseLeave="UserControl_MouseLeave"> 
    <UserControl.DataContext> 
     <ViewModels:ProfileViewModel/> 
    </UserControl.DataContext> 
    <Grid> 
     // some stuff done here 
    </Grid> 
</UserControl> 

mit Code-Behind:

using System.Windows.Controls; 

namespace test.Views 
{ 
    public partial class StatusView : UserControl 
    { 
     public StatusView() 
     { 
      InitializeComponent(); 
     } 
    } 
} 

und:

using System.Windows.Controls; 

namespace test.Views 
{ 
    public partial class ProfileView : UserControl 
    { 
     public ProfileView() 
     { 
      InitializeComponent(); 
     } 

     private void UserControl_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e) 
     { 
      // Update status bar text 
     } 

     private void UserControl_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e) 
     { 
      // Update status bar text 
     } 
    } 
} 

mit jedem Usercontrol seine eigene Ansichtsmodell als Datacontext gesetzt hat:

using System; 
using System.ComponentModel; 

namespace test.ViewModels 
{ 
    class StatusViewModel : INotifyPropertyChanged 
    { 
     private string _status = string.Empty; 
     public string Status 
     { 
      get { return _status; } 
      set { _status = value; OnPropertyChanged("Status"); } 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 
     private void OnPropertyChanged(string name) 
     { 
      PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); 
     } 

     public StatusViewModel() { } 
    } 
} 

und:

using System; 

namespace test.ViewModels 
{ 
    class ProfileViewModel 

     public ProfileViewModel() { } 

     // some stuff done here 
    } 
} 

Wie Sie aus dem Code sehen können, hat ProfileView MouseEnter und MouseLeave Ereignisse, auf denen ich TextBlock.Text Wert in StatusView setzen möchte (über seine ViewModel.Status Eigenschaft).

Jetzt nicht hier gezeigt, aber andere Klassen sollten auch in der Lage sein, den Wert der Statusleiste threadsicher zu aktualisieren, nach dem gleichen Prinzip.

Wie soll ich das erreichen?

Ich dachte, DependencyProperyes oder Delegaten und Events zu verwenden, aber ich weiß nicht, wie dies zu tun ist, da sowohl UserControls (und andere) in XML in MainWindow instanziiert werden, nicht durch Code-Behind. Dies ist, wie ich denke, sollte es getan werden (wenn ich MVVM folgen soll und Trennung der Arbeit habe - Designer entwirft, während Programmierer programmiert), aber das ist genau der Grund, warum ich nicht weiß, wie man das löst .

Danke für Hilfe.

Antwort

1

Ich empfehle dringend, MVVM Light zu verwenden.

Sie können MVVM Light Messenger verwenden. Es ist eine Klasse, die Austauschnachrichten zwischen Objekten ermöglicht. Messenger-Klasse ist vor allem für das Senden von Nachrichten zwischen Viewmodel verwendet: http://dotnetpattern.com/mvvm-light-messenger

PS: Ich hat auch Befehl Bindungen anstelle von Event-Handler zu verwenden, empfehlen (das ist nicht mvvm-like).