2016-06-24 11 views
0

Ich möchte eine einfache Schließen-Schaltfläche in einem WPF-Fenster implementieren. Das Fenster sieht grundsätzlich wie folgt:CommandParameter ist immer NULL

<Window x:Class="MyApplication.MainWindow" 
      xmlns="".... 
      ...." 
      Title="MainWindow" WindowState="Maximized" WindowStartupLocation="CenterScreen" x:Name="mainWindow"> 
<DockPanel LastChildFill="True"> 
     <Ribbon DockPanel.Dock="Top"> 
      <Ribbon.ApplicationMenu> 
       <RibbonApplicationMenu SmallImageSource="Resources/menu_16x16.png"> 
        <RibbonApplicationMenu.FooterPaneContent> 
         <RibbonButton Label="Beenden" 
             Command="{Binding CmdCloseApp}" 
             CommandParameter="{Binding ElementName=mainWindow}" 
             SmallImageSource="Resources/ende_16x16.png" 
             HorizontalAlignment="Right"/> 
        </RibbonApplicationMenu.FooterPaneContent> 
       </RibbonApplicationMenu> 
      </Ribbon.ApplicationMenu> 
     </Ribbon> 
</DockPanel> 
    </Window> 

Datacontext dieses Fenster ist Satz in seinem Code behindt zu einer Instanz von MainWindowViewModel

MainWindowViewModel:

public class MainWindowViewModel 
{ 
     public ICommand CmdCloseApp { get; set; } 

     public MainWindowViewModel() 
     { 
      CmdCloseApp = new RelayCommand<Window>(CloseApp); 
     } 

     public void CloseApp(Window w) 
     { 
      w.Close(); 
     } 
} 

In CloseApp w ist immer null. Alle anderen Befehle mit String-Parametern, etc .. funktionieren perfekt - mein einziges Problem ist, dass ich das Fensterelement nicht finde, finde einen Weg zu meinem Viewmodel.

danke für Ihre Hilfe!

EDIT Ich bin so traurig, ich versuchte es mit einem einfachen Knopfdruck und es funktionierte - Das Problem tritt nur bei RibbonButton

+0

in Command versuchen, die Eltern zu binden, statt Fensternamen. –

+4

Hallo, ich habe dein Sample ausprobiert und für mich funktioniert es einwandfrei, ich kann das Fenster als Parameter in meinem View-Modell bekommen. Verwenden Sie einen benutzerdefinierten Relay-Befehlscode? – Sivasubramanian

+0

@RohitPrakash danke für diesen Punkt, ich habe bereits versucht, die Lösung mit 'FindAnastor'- aber bleibt null – CeOnSql

Antwort

1

Edit: Nach der Änderung Anwendungsmenü Ribbonbutton Ihr Problem ist, dass Microsoft RibbonControlLibrary verwendet ein Popup-Menü, um die Schaltfläche zu halten, und das MainWindow ist nicht Teil des visuellen Baums des Popup-Menüs, so dass Ihre ElementName-Bindung das Fenster "mainWindow" nicht finden kann, sodass es CommandParameter
0 zuweist Verwenden Sie statisches Application.Current, um MainWindow zu erhalten, dann wird es funktionieren.
Achtung! Mainwindow ist die Eigenschaft Application Name, nicht der Name des Fensters

<Window x:Class="WpfRelayCommandParameter.MainWindow" 
    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:wpfRelayCommandParameter="clr-namespace:WpfRelayCommandParameter" 
    xmlns:ribbon="http://schemas.microsoft.com/winfx/2006/xaml/presentation/ribbon" 
    mc:Ignorable="d" 
    d:DataContext="{d:DesignInstance wpfRelayCommandParameter:MainWindowViewModel}" 
    Title="MainWindow" Height="350" Width="525" 
    x:Name="mainWindow"> 
<DockPanel LastChildFill="True"> 
    <DockPanel LastChildFill="True"> 
     <ribbon:Ribbon DockPanel.Dock="Top"> 
      <ribbon:Ribbon.ApplicationMenu> 
       <ribbon:RibbonApplicationMenu SmallImageSource="Resources/AppMenu.png"> 
        <ribbon:RibbonApplicationMenu.FooterPaneContent> 
         <ribbon:RibbonButton Label="Beenden" 
            Command="{Binding CmdCloseApp}" 
            CommandParameter="{Binding MainWindow, Source={x:Static Application.Current}}" 
            SmallImageSource="Resources/Exit.png" 
            HorizontalAlignment="Right" Click="ButtonBase_OnClick"/> 
        </ribbon:RibbonApplicationMenu.FooterPaneContent> 
       </ribbon:RibbonApplicationMenu> 
      </ribbon:Ribbon.ApplicationMenu> 
     </ribbon:Ribbon> 
    </DockPanel> 
</DockPanel> 

persönlich an das Fenster über eine Schnittstelle gehen ich Rückrufe bevorzugen, die speziell nach Ihrem Ansichtsmodell Bedürfnisse sein kann und werden in Unit-Tests verspottet:

<Window x:Class="WpfRelayCommandParameter.MainWindow" 
    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:wpfRelayCommandParameter="clr-namespace:WpfRelayCommandParameter" 
    mc:Ignorable="d" 
    d:DataContext="{d:DesignInstance wpfRelayCommandParameter:MainWindowViewModel}" 
    Title="MainWindow" Height="350" Width="525" 
    x:Name="mainWindow"> 
<Grid> 
    <Button Content="Close Window" 
      Command="{Binding CmdCloseApp}" 
      VerticalAlignment="Top" 
      HorizontalAlignment="Left" /> 
</Grid> 

-Code

public partial class MainWindow : Window, IMainWindow 
{ 
    public MainWindow() 
    { 
     DataContext = new MainWindowViewModel(this); 
     InitializeComponent(); 
    } 
} 

public interface IMainWindow 
{ 
    void Close(); 
} 

public class MainWindowViewModel 
{ 
    private readonly IMainWindow _mainWindow; 

    public MainWindowViewModel() : this(null) 
    { 
     // Design time 
    } 

    public MainWindowViewModel(IMainWindow mainWindow) 
    { 
     _mainWindow = mainWindow; 
     CmdCloseApp = new RelayCommand(CloseApp); 
    } 

    public ICommand CmdCloseApp { get; set; } 

    public void CloseApp(object parameter) 
    { 
     _mainWindow.Close(); 
    } 
} 

Hinweis mögliche Probleme mit der Art und null für CanExecute CanExecute on RelayCommand

+0

Danke, es funktioniert jetzt (über eine Schnittstelle). Perfekte Erklärung warum meine Lösung nicht funktioniert :) – CeOnSql