代码之家  ›  专栏  ›  技术社区  ›  Kevin

WPF ListView光标更改

  •  1
  • Kevin  · 技术社区  · 15 年前

    我有一个可滚动的时间表,是从列表视图。 当鼠标聚焦在列表视图上时。

    光标是一只张开的手,使用代码

    <ControlTemplate.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter Property="Cursor" Value="openHand.cur"/>
        </Trigger>                    
    </ControlTemplate.Triggers>
    

    但我想知道。如果在列表视图上按鼠标左键,我能做些什么吗? 如果是,则将光标更改为闭合的手? 提前谢谢!

    1 回复  |  直到 15 年前
        1
  •  2
  •   Ray Burns    15 年前

    WPF没有“IsMouseLeftButtonDown”属性,但您可以创建自己的附加属性来执行此操作,然后对其进行触发。这比向单个控件添加mouseLeftButtonDown事件处理程序要干净得多。

    这样做:

    1. 为ismouseLeftButtonDown(以及其他按钮)创建继承的附加属性
    2. 创建“已启用”的附加属性以自动设置所需的事件处理程序。
    3. 直接在控件或任何包含控件上设置“已启用”属性。
    4. 在触发器或多触发器中使用“IsMouseLeftButtonDown”属性

    以下是它的外观:

    <Window ...
            local:MouseExtensions.Enabled="true" />  <!-- Set the handlers -->
      ...
      <ControlTemplate.Triggers>
        <Trigger Property="IsMouseOver" Value="True" >
          <Setter Property="Cursor" Value="openHand.cur"/>
        </Trigger>
        <MultiTrigger>
          <MultiTrigger.Conditions>
            <Condition Property="IsMouseOver" Value="True" />
            <Condition Property="local:MouseExtensions.IsMouseLeftButtonDown" Value="True" />
          </MultiTrigger.Conditions>
          <Setter Property="Cursor" Value="closedHand.cur" />
        </MultiTrigger>
      </ControlTemplate.Triggers>
    

    下面是如何实现附加属性:

    public class MouseExtensions : DependencyObject
    {
      // IsMouseLeftButtonDown
      public static bool GetIsMouseLeftButtonDown(DependencyObject obj) { return (bool)obj.GetValue(IsMouseLeftButtonDownProperty); }
      public static void SetIsMouseLeftButtonDown(DependencyObject obj, bool value) { obj.SetValue(IsMouseLeftButtonDownProperty, value); }
      public static readonly DependencyProperty IsMouseLeftButtonDownProperty = DependencyProperty.RegisterAttached("IsMouseLeftButtonDown", typeof(bool), typeof(MouseExtensions), new FrameworkPropertyMetadata
      {
        Inherits=true,
      });
    
    
      // IsMouseMiddleButtonDown
      public static bool GetIsMouseMiddleButtonDown(DependencyObject obj) { return (bool)obj.GetValue(IsMouseMiddleButtonDownProperty); }
      public static void SetIsMouseMiddleButtonDown(DependencyObject obj, bool value) { obj.SetValue(IsMouseMiddleButtonDownProperty, value); }
      public static readonly DependencyProperty IsMouseMiddleButtonDownProperty = DependencyProperty.RegisterAttached("IsMouseMiddleButtonDown", typeof(bool), typeof(MouseExtensions), new FrameworkPropertyMetadata
      {
        Inherits=true,
      });
    
      // IsMouseRightButtonDown
      public static bool GetIsMouseRightButtonDown(DependencyObject obj) { return (bool)obj.GetValue(IsMouseRightButtonDownProperty); }
      public static void SetIsMouseRightButtonDown(DependencyObject obj, bool value) { obj.SetValue(IsMouseRightButtonDownProperty, value); }
      public static readonly DependencyProperty IsMouseRightButtonDownProperty = DependencyProperty.RegisterAttached("IsMouseRightButtonDown", typeof(bool), typeof(MouseExtensions), new FrameworkPropertyMetadata
      {
        Inherits=true,
      });
    
      // Enabled
      public static bool GetEnabled(DependencyObject obj) { return (bool)obj.GetValue(EnabledProperty); }
      public static void SetEnabled(DependencyObject obj, bool value) { obj.SetValue(EnabledProperty, value); }
      public static readonly DependencyProperty EnabledProperty = DependencyProperty.RegisterAttached("Enabled", typeof(bool), typeof(MouseExtensions), new PropertyMetadata
      {
        PropertyChangedCallback = (obj, e) =>
          {
            var element = (FrameworkElement)obj;
            if((bool)e.OldValue)
            {
              element.PreviewMouseDown -= Update;
              element.PreviewMouseUp -= Update;
              element.MouseEnter -= Update;
              element.MouseLeave -= Update;
            }
            if((bool)e.NewValue)
            {
              element.PreviewMouseDown += Update;
              element.PreviewMouseUp += Update;
              element.MouseEnter += Update;
              element.MouseLeave += Update;
            }
          }
      });
    
      private static void Update(object sender, MouseEventArgs e)
      {
        var element = (FrameworkElement)sender;
        bool inside = e.RoutedEvent!=Mouse.MouseLeaveEvent;
        SetIsMouseLeftButtonDown(element, inside && e.LeftButton==MouseButtonState.Pressed);
        SetIsMouseMiddleButtonDown(element, inside && e.MiddleButton==MouseButtonState.Pressed);
        SetIsMouseRightButtonDown(element, inside && e.RightButton==MouseButtonState.Pressed);
      }
    }
    

    工作原理:“已启用”propertychangedcallback将“update”方法添加为四个鼠标事件的处理程序。当其中一个事件发生时,将检查当前鼠标按钮状态,并在“已启用”设置为true的元素上更新is_uuu ButtonDown属性。从那里,这些属性通过逻辑树和可视化树继承下来。但是,如果收到mouseleave,则所有这些属性都设置为false,因为在鼠标再次位于“启用”的元素上之前,不会再次收到任何鼠标事件。