代码之家  ›  专栏  ›  技术社区  ›  Daniel Sam

如何在WPF中的StackPanel的MouseEnter上执行命令绑定?

  •  3
  • Daniel Sam  · 技术社区  · 15 年前

    我在用MVVM。

    <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}"/>
    

    你知道吗?

    3 回复  |  直到 15 年前
        1
  •  2
  •   STO    15 年前

    我错了,输入绑定不能解决问题。您可以为此使用附加属性:

    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;
    }
    
    }
    
        2
  •  2
  •   Shaun Bowe    15 年前

    首先,您需要为mouse enter声明一个行为。这基本上将事件转换为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);
          }
        }
      }
    

    然后您只需要在视图模型中创建该命令并在视图中引用它。behaviors:namespace应该只指向创建该行为的位置。每次需要将事件转换为视图模型中的命令时,我都会使用此模式。

    <Grid>
        <StackPanel behaviors:MouseEnterBehavior.MouseEnter="{Binding MouseEnteredCommand}"
                    Height="150"
                    Width="150"
                    Background="Red">
    
        </StackPanel>
    </Grid>
    
        3
  •  0
  •   STO    15 年前