none
Treeview中使用鼠标移动选择Item的问题 RRS feed

  • 问题

  • TreeView中默认的选中操作是通过单击鼠标进行选中,我想通过鼠标移动上去就使其处于选中状态。然后我的代码是这样的:

     

    <Window.Resources>
    
      <ContextMenu x:Key="item">
       <MenuItem Header="itemDelete" Click="Level2_Click"></MenuItem>
      </ContextMenu>
    
      <ContextMenu x:Key="list">
       <MenuItem Header="level1 delete" Click="Level1_Click"></MenuItem>
      </ContextMenu>
      
      <HierarchicalDataTemplate DataType= "{x:Type src:FriendList}"
      ItemsSource = "{Binding Path=Friends}">
       <Label Content="{Binding Path=ListName}"/>
       <HierarchicalDataTemplate.ItemContainerStyle>
        <Style TargetType="TreeViewItem">
         <Setter Property="ContextMenu" Value="{StaticResource item}">
         </Setter>
         <Style.Triggers>
          <Trigger Property="IsMouseOver" Value="True">
           <Setter Property="IsSelected" Value="True"></Setter>
          </Trigger>
         </Style.Triggers>
        </Style>
       </HierarchicalDataTemplate.ItemContainerStyle>
      </HierarchicalDataTemplate>
      <DataTemplate DataType="{x:Type src:Member}">
       <Label Name="label" Content="{Binding Path=Account}" MouseDoubleClick="label_MouseDoubleClick"/>
      </DataTemplate>
    
     </Window.Resources>
     <StackPanel>
      <TreeView Height="100">
       <TreeView.ItemContainerStyle>
        <Style TargetType="TreeViewItem">
         <Setter Property="ContextMenu" Value="{StaticResource list}">
         </Setter>
         <Style.Triggers>
          <Trigger Property="IsMouseOver" Value="True">
           <Setter Property="IsSelected" Value="True"></Setter>
          </Trigger>
         </Style.Triggers>
        </Style>
       </TreeView.ItemContainerStyle>
      </TreeView>
      
     </StackPanel>
    

    可以跟我预期的一样运行,但就是有时候会出现一个问题,当我展开第二个菜单的时候,鼠标在二级菜单上晃荡,二级菜单会正确地随着鼠标的位置而处于被选中状态,当我的鼠标从二级菜单移到一级菜单上时,就失效了,一级菜单无法处于被选中状态。而且有时候二级菜单的第一个无法始终无法通过鼠标移动处于被选中的状态。

     

    2011年6月25日 3:44

答案

全部回复

  • 我初步看了一下你的代码,我觉得应该会出现你描述的问题,因为是这样,对于TreeView,这个IsMouseOver属性有些不同,因为这个属性不仅仅是鼠标指针下面的Item为True,这个Item的父级也是True的,所以我没有尝试你的代码。

    根据你的需求,我写了一个方法,你可以使用:

    https://skydrive.live.com/?cid=41e44c402aaada87&sa=304315356#!/?cid=41e44c402aaada87&sc=documents&nl=1&uc=1&id=41E44C402AAADA87%21312


    Sheldon _Xiao[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • 已标记为答案 Behindmoon 2011年6月29日 13:10
    2011年6月28日 7:39
    版主
  • 太感谢了!劳您费心,我下载了代码看了很久,有些似懂非懂,我试着解释一下流程,您看看对不对:

    第一步:通过鼠标的移动进入到OnMouseTransition事件中,由Mouse.DirectlyOver判定是否悬停在TreeViewItem内的某个元素上。是的话引发UpdateOverItemEvent事件。

    第二步:在UpdateOverItemEvent事件内设置_currentItem,然后计算IsMouseDirectlyOverItemProperty依赖属性,进而触发CalculateIsMouseDirectlyOverItem

    第三步:在CalculateIsMouseDirectlyOverItem内进行属性所在对象与_currentItem进行比较。得出是否依赖属性值。(这里看得好晕哦,_currentItem.InvalidateProperty(IsMouseDirectlyOverItemProperty);这样调用后,item对象不是难道有可能不是_currentItem吗?)

    还有,注册依赖属性的时候,这样注册为什么不可以呀:public static readonly DependencyProperty IsMouseDirectlyOverItemProperty = DependencyProperty.Register("IsMouseDirectlyOverItem", typeof(bool), typeof(MyTreeViewHelper), new FrameworkPropertyMetadata(null, new CoerceValueCallback(CalculateIsMouseDirectlyOverItem)));

    另外,在使用的时候,

          <TreeView.Resources>
            <Style TargetType="TreeViewItem">
              <Style.Triggers>
                <Trigger Property="local:MyTreeViewHelper.IsMouseDirectlyOverItem" Value="True">
                  <Setter Property="IsSelected" Value="True" />
                </Trigger>
              </Style.Triggers>
              
              <Setter Property="Padding" Value="5" />
            </Style>
          </TreeView.Resources>
    

    这样设置在我这里是不行的,而要分别放到<TreeView.ItemContainerStyle>与<HierarchicalDataTemplate.ItemContainerStyle>内才可以。为什么不能用上面的方式统一进行设置呢?

    还有,TreeViewItem中也有一个IsMouseDirectlyOver属性,用这个不行吗?

    问题较多,再次感谢您的不吝赐教

    2011年6月29日 13:10