2009-11-17 3 views
0

droit, ce que j'ai est:Comment puis-je lier une commande d'un contrôle dans le modèle à mon ViewModel

<Window x:Class="WpfGettingThingsDone.View.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    AllowsTransparency="True" 
    Background="Transparent" 
    WindowStyle="None"  
    Title="{Binding Title}" Height="300" Width="300"> 
    <Window.Resources> 
     <ResourceDictionary> 
      <Style x:Key="WindowBorderBackground" TargetType="{x:Type Border}"> 
       <Setter Property="Background"> 
        <Setter.Value> 
         <LinearGradientBrush StartPoint="0,1" EndPoint="1,0"> 
          <GradientStop Color="#FF222222" Offset="0" /> 
          <GradientStop Color="#FF222222" Offset="0.2" /> 
          <GradientStop Color="#FFAAAAAA" Offset="0.6" /> 
          <GradientStop Color="#FF222222" Offset="0.7" /> 
          <GradientStop Color="#FFAAAAAA" Offset="0.9" /> 
          <GradientStop Color="#FF222222" Offset="1" /> 
         </LinearGradientBrush> 
        </Setter.Value> 
       </Setter> 
      </Style> 

      <Style x:Key="WindowHeaderedContent" TargetType="{x:Type HeaderedContentControl}"> 
       <Setter Property="HeaderTemplate"> 
        <Setter.Value> 
         <DataTemplate> 
          <Border 
           Background="Black" 
           BorderBrush="Black" 
           BorderThickness="1" 
           CornerRadius="5,5,0,0" 
           Padding="4" 
           SnapsToDevicePixels="True" 
           > 
           <DockPanel> 
            <Button DockPanel.Dock="Right" Command="{Binding Path=CloseCommand}">X</Button> 
            <TextBlock 
             FontSize="14" 
             FontWeight="Bold" 
             Foreground="White" 
             HorizontalAlignment="Center" 
             Text="{TemplateBinding Content}" /> 
           </DockPanel> 
          </Border> 
         </DataTemplate> 
        </Setter.Value> 
       </Setter> 
      </Style> 
     </ResourceDictionary> 
    </Window.Resources> 

    <Border CornerRadius="5" Style="{StaticResource WindowBorderBackground}"> 
     <HeaderedContentControl Header="Current Contexts" 
           Style="{StaticResource WindowHeaderedContent}" 
           > 
     </HeaderedContentControl> 
    </Border> 
</Window> 

tire Au fond d'une fenêtre avec un joli fond gradient, en utilisant un HeaderedContentControl pour créer la barre de titre, qui utilise un HeaderTemplate pour y placer le bouton x.

Comme si:

alt text

Cependant, comme vous pouvez le voir, je l'ai essayé lier la commande du bouton X (fermer) le CloseCommand dans mon ViewModel. En supposant que mon ViewModel est correct et que mon manque de compréhension de la liaison de données WPF est le problème, qu'est-ce que je fais mal? Cela ne peut-il pas être fait comme j'essaye?

(Note: Aux fins de cette question, je fusionné toutes les ressources utilisées par la fenêtre dans le dictionnaire de ressources Windows.)

Edit: Depuis Sam a suggéré mon DataContext pour ma fenêtre n'est pas réglé, Je vais préciser qu'il est défini, mais fait dans le code derrière App.Xaml quand il crée la MainWindow.

/// <summary> 
/// Interaction logic for App.xaml 
/// </summary> 
public partial class App : Application 
{ 
    protected override void OnStartup(StartupEventArgs e) 
    { 
     base.OnStartup(e); 

     MainWindow mainWindow = new MainWindow();    
     var viewModel = new MainWindowViewModel(); 

     viewModel.RequestClose += (s, ev) => mainWindow.Close(); 

     mainWindow.DataContext = viewModel; 

     mainWindow.Show(); 
    } 
} 

Répondre

2

Voici une autre tentative. Votre bouton est dans le DataTemplate pour l'en-tête de HeaderedContentControl. Ce modèle de données a un contexte de données différent du contrôle parent. Son contexte de données est implicitement la valeur de la propriété Header. Donc, pour résoudre votre problème, vous devez faire

<HeaderedContentControl Header="{Binding}" .../> 

L'instruction vide {} Binding signifie « lier la propriété à la DataContext de ce contrôle ».

Vous pouvez également utiliser une liaison RelativeSource dans laquelle vous définissez la liaison de commande. Quelque chose comme:

<Button DockPanel.Dock="Right" 
    Command="{Binding Path=DataContext.CloseCommand, RelativeSource={RelativeSource AncestorType={x:Type HeaderedContentControl}}}">...</Button> 
+0

Ta, merci beaucoup :) – Sekhat

0

Dans votre bouton, vous spécifiez le chemin de la liaison, mais pas la source de données. Je pense que ce qui vous manque est de définir le DataContext de votre fenêtre pour être le ViewModel. Vous avez besoin de quelque chose comme

<Window ... DataContext="{StaticResource myViewModel}"> 
... 
+0

En fait, désolé, c'est le cas. App.Xaml.cs configure le contexte de données pour ma fenêtre principale à partir de la fonction OnStartup. – Sekhat

Questions connexes