WPF ListView 選中問題


WPF ListView 選中問題

 摘自:http://www.cnblogs.com/BBHor/archive/2013/04/28/VisualTreeHelper-PreviewMouseDown.html

在項目中遇到了這樣的問題,ListView通過數據綁定,有模板的情況下ListViewItem 里面的子控件點擊之后默認是子控件獲得焦點而不是Item獲的焦點。

往往需要獲取一個ListViewItem  而不是他的子控件,這時候應該怎么辦呢?

先看前台XAML:

復制代碼
 1  <ListView x:Name="lv_VMlist"
 2                           PreviewMouseDown="lv_VMlist_PreviewMouseDown"
 3                           SelectionChanged="lv_VMlist_SelectionChanged">
 4                     <ListView.View>
 5                         <GridView>
 6                             <GridView.Columns>
 7                                 <GridViewColumn Width="100"
 8                                                 DisplayMemberBinding="{Binding CallerID}"
 9                                                 Header="主叫方號碼" />
10                                 <GridViewColumn Width="110"
11                                                 DisplayMemberBinding="{Binding Duration}"
12                                                 Header="語音郵件長度" />
13                                 <GridViewColumn Width="70"
14                                                 DisplayMemberBinding="{Binding External}"
15                                                 Header="是否是外線" />
16                                 <GridViewColumn Width="80"
17                                                 DisplayMemberBinding="{Binding Type,
18                                                                                Converter={StaticResource etsc}}"
19                                                 Header="類型" />
20                                 <GridViewColumn Width="70"
21                                                 DisplayMemberBinding="{Binding AttachCount}"
22                                                 Header="附件個數" />
23                                 <GridViewColumn Width="120"
24                                                 DisplayMemberBinding="{Binding Time}"
25                                                 Header="時間" />
26                                 <GridViewColumn Width="180" Header="操作">
27                                     <GridViewColumn.CellTemplate>
28                                         <HierarchicalDataTemplate>
29                                             <StackPanel Name="stackPanel" Orientation="Horizontal">
30                                                 <Button Name="btnPlay"
31                                                         Margin="0,0,5,0"
32                                                         Command="{Binding RelativeSource={RelativeSource FindAncestor,
33                                                                                                          AncestorLevel=1,
34                                                                                                          AncestorType={x:Type ListView}},
35                                                                           Path=DataContext.OnPlay}"
36                                                         Content="播放"
37                                                         Focusable="False" />
38                                                 <Button Name="btnStop"
39                                                         Margin="0,0,5,0"
40                                                         Command="{Binding RelativeSource={RelativeSource FindAncestor,
41                                                                                                          AncestorLevel=1,
42                                                                                                          AncestorType={x:Type ListView}},
43                                                                           Path=DataContext.OnStop}"
44                                                         Content="停止" />
45                                                 <Button Name="btnSaveAs"
46                                                         Margin="0,0,5,0"
47                                                         Click="btnSaveClick"
48                                                         Content="另存為"
49                                                         ToolTip="將語音郵件保存到本地" />
50                                                 <Button Name="btnDel"
51                                                         Margin="0,0,5,0"
52                                                         Command="{Binding RelativeSource={RelativeSource FindAncestor,
53                                                                                                          AncestorLevel=1,
54                                                                                                          AncestorType={x:Type ListView}},
55                                                                           Path=DataContext.OnDelete}"
56                                                         Content="刪除"
57                                                         ToolTip="刪除本條語音郵件" />
58                                                 <Button Name="btnSendTo"
59                                                         Margin="0,0,5,0"
60                                                         Content="轉發"
61                                                         ToolTip="將本條語音郵件轉發給他人" />
62                                             </StackPanel>
63                                         </HierarchicalDataTemplate>
64                                     </GridViewColumn.CellTemplate>
65                                 </GridViewColumn>
66                             </GridView.Columns>
67                         </GridView>
68                     </ListView.View>
69                 </ListView>
復制代碼

要下手去尋找這時候得借助WPF里面的一個神奇的類:VisualTreeHelper  有了這個類幾乎能得到界面的任何東西。當然了,先行條件是在子控件的事件觸發之前就要出發一個事件去獲取ListViewItem,此時我們想到一個事件就是PreviewMouseDown,因為他是鼠標事件,所以優先級比較高,當他觸發了之后才會觸發子控件的一些Click事件等

 

復制代碼
 1   private void lv_VMlist_PreviewMouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
 2         {
 3             int index = -1;
 4             DependencyObject depObj = e.OriginalSource as DependencyObject;
 5 
 6             if (depObj == null) return;
 7 
 8             do
 9             {
10                 depObj = VisualTreeHelper.GetParent(depObj);
11 
12                 //有可能是點擊到listviewitem之外的東西,例如滾動條,這時候會為null
13                 if (depObj == null) break;
14 
15                 //得到listviewitem
16                 if (depObj.GetType() == typeof(ListViewItem))
17                 {
18                     //再去獲取父級,用來得到索引
19                     DependencyObject parent = VisualTreeHelper.GetParent(depObj);
20 
21                     for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
22                     {
23                         if (depObj == VisualTreeHelper.GetChild(parent, i))
24                         {
25                             //得到索引后馬上跳出
26                             index = i;
27                             break;
28                         }
29                     }
30                     break;
31                 }
32             }
33             while (depObj != null);
34 
35             //證明已經找到
36             if (index > -1)
37             {
38                 lv_VMlist.SelectedIndex = index;
39             }
40         }
復制代碼

 

但是需要注意的是,這樣寫思路倒是簡單,就是數據量大的清空可能會影響效率,慎用!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM