2016-10-26 2 views
0

Ich habe ein WPF-Fenster mit einem Raster mit 4 Rechtecken. Eine davon hat eine <frame> zum Anzeigen von Seiten, die in meiner Anwendung verwendet wird. Ich möchte diesen Schaltflächen sowohl auf meinen Fenstern als auch auf den Seiten Befehle hinzufügen.Befehle im Fenster mit Rahmen können nicht ausgelöst werden

Dinge, die ich verwende: MVVM, Fenster als Mainwindow und Pages als contentpublisher in einem Rahmen.

Zum Beispiel möchte ich Applicationwide mit einer Schaltfläche und einem Befehl anmelden. Während dies auf der Seite in meinem Frame geschieht, gibt es keine Fehler, aber das kann ich nicht im Fenster tun.

Ich frage mich, ob die Fenster den Fokus verlieren, so dass es dieses Ereignis beim Navigieren zu einer Seite im Rahmen nicht auslösen kann. Also habe ich versucht, das Fenster zu erhalten mit folgenden Befehl Bindung:

<Button Content="&#xE143;" FontFamily="Segoe UI Symbol" 
    Command="{Binding CommandWhichDoesNotFire, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type vw:MainViewModel}}}" 
    Width="32"> 

In meinem ViewModel „MainViewModel“ Ich habe ein öffentliches ICommand Eigentum und ich initialisieren es an dem Konstruktor:

public ICommand CommandWhichDoesNotFire; 
    public MainViewModel() 
    { 
     MessageBox.Show("VM is real"); 

     CommandWhichDoesNotFire= new TestCommand(); 
    } 

Die DataContext meines MainView wird im hinter-code BEFORE InitilizeComponents(); gesetzt Klicken auf die Schaltfläche startet keinen Aufruf meines Befehls. Es feuert einfach überhaupt nicht. Was vermisse ich Jungs?

+0

Können Sie mehr Code mit minimalem Fenster und wie Sie den DataContext setzen? Es ist schwierig, dir ohne es zu helfen. – XAMlMAX

+0

Werden Binding-Fehler in der Ausgabe der VS-Konsole gemeldet? Kannst du Snoop hochlaufen und sehen, ob die Bindung erfolgreich war? – LordWilmore

Antwort

0

sollten Sie haben:

public ICommand CommandWhichDoesNotFire{get;set;} 
public MainViewModel() 
{ 
    MessageBox.Show("VM is real"); 

    CommandWhichDoesNotFire= new TestCommand(MyCommand); 
} 
private void MyCommand(object obj){ 
//Whatever you want to do 
} 
0

Ich glaube, ich habe eine Lösung für Ihr Problem gefunden.
Die Frame aus irgendeinem Grund ist Elternteil nicht die DataContext davon erben, auch wenn Sie die DataContext explizit wie so gesetzt:

DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:MainWindow}}}" 

es immer noch nicht funktioniert. Was sie tut es nur die DataContext des Rahmens setzt aber nicht untergeordneten Elemente: Frame's Data Context is set
Und hier ist die DataContext eines Kindes Element:
Child element Data Context is NULL!
Nun ist diese mich denken ließ, dass das, was wir immer über WPF geliebt haben und es ist Controls war die Fähigkeit, die DataContext von ihrem Elternteil zu erben, mit Ausnahme von ContextMenu und jetzt die Frame. Hier ist der Ansatz, den ich nahm, als ich einen frist Blick auf oyur Problem hatte:

<Window x:Class="WpfApplication1.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:local="clr-namespace:WpfApplication1" 
    mc:Ignorable="d" 
    Title="MainWindow" Height="350" Width="525"> 
<Window.DataContext> 
    <local:MainVM/> 
</Window.DataContext> 
<Window.Resources> 
    <!--<local:MainVM x:Key="mainVM"/>--> 
    <local:LoginPage x:Key="login" /> 
    <!--DataContext="{StaticResource mainVM}"--> 
    <ControlTemplate x:Key="ctrlTmpl"> 
     <local:LoginPage/> 
    </ControlTemplate> 

</Window.Resources> 
<Grid> 
    <!--<Button x:Name="button" Content="Do something" Click="btnDoSomething" HorizontalAlignment="Left" Margin="221,60,0,0" VerticalAlignment="Top" Width="75"/>--> 
    <!--<Control Template="{StaticResource ctrlTmpl}"/> This works--> 
    <Frame Content="{StaticResource login}" DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:MainWindow}}}" /> 
</Grid> 


Dann dachte ich dir eine andere Art und Weise tun:

<Window x:Class="WpfApplication1.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:local="clr-namespace:WpfApplication1" 
    mc:Ignorable="d" 
    Title="MainWindow" Height="350" Width="525"> 
<!--<Window.DataContext> 
    <local:MainVM/> 
</Window.DataContext>--> 
<Window.Resources> 
    <local:MainVM x:Key="mainVM"/> 
    <local:LoginPage x:Key="login" DataContext="{StaticResource mainVM}"/> 
    <!----> 
    <ControlTemplate x:Key="ctrlTmpl"> 
     <local:LoginPage/> 
    </ControlTemplate> 

</Window.Resources> 
<Grid> 
    <!--<Button x:Name="button" Content="Do something" Click="btnDoSomething" HorizontalAlignment="Left" Margin="221,60,0,0" VerticalAlignment="Top" Width="75"/>--> 
    <!--<Control Template="{StaticResource ctrlTmpl}"/> This works--> 
    <Frame Content="{StaticResource login}"/> 
</Grid> 


Beachten Sie, wie ich die VM enthalten in den Ressourcen und dann diese Instanz verwendet, um die Kontrollen DataContext sein. An diesem Punkt, wenn ich den Knopf in meiner LoginPage.xaml klicke, der übrigens ein UserControl ist, löst es den Befehl aus, der in meinem MainVM gefunden wird. An dieser Stelle würden Sie die WindowDataContext in der Code-behind wie so zuweisen müssen:

public MainWindow() 
    { 
     InitializeComponent(); 

     var vm = this.TryFindResource("mainVM"); 
     if(vm != null) 
     { 
      this.DataContext = vm; 
     } 
    } 

An diesem Punkt Sie irgendeine Art von Trigger verwenden können, durch die Seiten zu navigieren und verschiedenen Page s oder UserControl s verwenden.HTH
P.S. Wenn ich eine Chance bekomme, werde ich einige Informationen über das Kontextmenü und Frame von MSDN aktualisieren. Happy Coding

Verwandte Themen