2010-06-30 70 views
3

我正在使用MVVM。如何在WPF中的StackPanel的MouseEnter上執行命令綁定?

<ItemsControl ItemsSource="{Binding AllIcons}" Tag="{Binding}"> 
    <ItemsControl.ItemTemplate> 
     <DataTemplate> 
      <StackPanel> 
       <Label HorizontalAlignment="Right">x</Label> 
       <Image Source="{Binding Source}" Height="100" Width="100" /> 
       <Label HorizontalAlignment="Center" Content="{Binding Title}"/> 
      </StackPanel> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ItemsControl> 

看起來很好。如果我用這個命令把一個按鈕,在堆疊面板:

<Button Command="{Binding Path=DataContext.InvasionCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}}" CommandParameter="{Binding}"/> 

我能捕捉到命令。但是,我想在鼠標進入堆棧面板時執行命令綁定,而不是單擊按鈕。

任何想法?

回答

2

我的錯,輸入綁定並不能解決問題。您可以使用以下附加屬性:

public static class MouseEnterCommandBinding 
{ 
    public static readonly DependencyProperty MouseEnterCommandProperty = DependencyProperty.RegisterAttached(
    "MouseEnterCommand", 
    typeof(ICommand), 
    typeof(MouseEnterCommandBinding), 
    new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.AffectsRender) 
); 

public static void SetMouseEnterCommand(UIElement element, ICommand value) 
{ 
    element.SetValue(MouseEnterCommandProperty, value); 
    element.MouseEnter += (s,e) => 
    { 
     var uiElement = s as UIElement; 
     var command = GetMouseEnterCommand(uiElement); 
     if (command != null && command.CanExecute(uiElement.CommandParameter)) 
      command.Execute(uiElement.CommandParameter); 
    } 
} 
public static ICommand GetMouseEnterCommand(UIElement element) 
{ 
    return element.GetValue(MouseEnterCommandProperty) as ICommand; 
} 

} 
+0

有什麼辦法可以用MVVM架構來做到這一點? – Daniel 2010-06-30 19:35:41

+0

當然,您可以將該依賴屬性綁定到您的視圖模型的命令,如: 'xmlns:view =「使用MouseEnterCommandBinding類導入您的名稱空間」 ... <型號:YourModel /> ' 順便說一句,的UIElement不包含CommandParameter財產,直到它實現ICommandSource接口,所以您需要更改SetMouseEnterCommand方法反映這個事實。 – STO 2010-07-01 08:58:00

2

首先,您需要聲明鼠標輸入的行爲。這基本上將事件轉換爲ViewModel中的命令。

public static class MouseEnterBehavior 
    { 
    public static readonly DependencyProperty MouseEnterProperty = 
     DependencyProperty.RegisterAttached("MouseEnter", 
              typeof(ICommand), 
              typeof(MouseEnterBehavior), 
              new PropertyMetadata(null, MouseEnterChanged)); 

    public static ICommand GetMouseEnter(DependencyObject obj) 
    { 
     return (ICommand)obj.GetValue(MouseEnterProperty); 
    } 

    public static void SetMouseEnter(DependencyObject obj, ICommand value) 
    { 
     obj.SetValue(MouseEnterProperty, value); 
    } 

    private static void MouseEnterChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) 
    { 
     UIElement uiElement = obj as UIElement; 

     if (uiElement != null) 
     uiElement.MouseEnter += new MouseEventHandler(uiElement_MouseEnter); 
    } 

    static void uiElement_MouseEnter(object sender, MouseEventArgs e) 
    {  
     UIElement uiElement = sender as UIElement; 
     if (uiElement != null) 
     { 
     ICommand command = GetMouseEnter(uiElement); 
     command.Execute(uiElement); 
     } 
    } 
    } 

然後你只需要在你的視圖模型中創建該命令並在視圖中引用它。行爲:名稱空間應該指向您創建該行爲的任何位置。每當我需要將事件轉換爲視圖模型中的命令時,我都會使用此模式。

<Grid> 
    <StackPanel behaviors:MouseEnterBehavior.MouseEnter="{Binding MouseEnteredCommand}" 
       Height="150" 
       Width="150" 
       Background="Red"> 

    </StackPanel> 
</Grid>