2013-12-13 26 views
4

首先有與擴展器不退縮的空間崩潰的問題。
基於邊界看起來,ListView並不縮小,而是Expander不縮小。
以下代碼修復了收縮問題。
ListBox control does not shrink
這會失去虛擬化,但是我確定,因爲這是儘可能多的數據,因爲我需要顯示。ListView跳轉或不縮小

<ListView.ItemsPanel> 
    <ItemsPanelTemplate> 
     <StackPanel/> 
    </ItemsPanelTemplate> 
</ListView.ItemsPanel> 

但後來出現了一個新問題。
如果你打開任何兩級Expander並嘗試點擊複選框,它會經常跳轉,有時會跳得太多,以至於點擊錯過了複選框。
一直滾動到底部,所以複選框不在底部(它下面有一些擴展器)。
然後點擊,它會跳轉,很可能會錯過該項目。
我可以多次嘗試檢查或取消選中最後一行。
很確定這是因爲點擊正在被處理兩次以及在兩者之間移動。

那麼如何解決這兩個問題呢?
1.收縮縮小/放棄空間?
2.複選框不跳?

嘗試通過調度程序,UpdateLayout(),InvalidateVisual()和Height = Double.NaN進行刷新。
StackPanel不是問題,因爲我可以刪除它並使用Exp1,但仍然存在問題。
有一個類似的問題之前,雙擊SelectedItem,我可以修復吃第二次點擊,但該修復程序無法在這裏工作。 MissClick
嘗試過TreeView,但我沒有在每個級別顯示相同的信息,所以它不起作用。
但我接受另一種方法。
兩級層次結構,只需要在第二級上的複選框。

對不起,很多代碼,但這是一個完整的程序來重現問題。
Exp1與Exp2完全相同,但並非真正需要重現問題,但它反映了真實程序以防有人提出備用解決方案。

<Window x:Class="ListViewJump.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525"> 
    <Grid> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="165"/> 
     </Grid.ColumnDefinitions> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="*" /> 
     </Grid.RowDefinitions> 
     <ScrollViewer Grid.Row="0" Grid.Column="0" 
         HorizontalScrollBarVisibility="Disabled" 
         VerticalScrollBarVisibility="Visible"> 
      <StackPanel> 
       <Expander IsExpanded="False" Header="Exp1" BorderThickness="2" BorderBrush="Green"> 
        <ListView ItemsSource="{Binding Path=List1}" 
           HorizontalAlignment="Left" BorderThickness="2" BorderBrush="Orange"> 
         <ListView.ItemsPanel> 
          <ItemsPanelTemplate> 
           <StackPanel/> 
          </ItemsPanelTemplate> 
         </ListView.ItemsPanel> 
         <ListView.ItemTemplate > 
          <DataTemplate> 
           <Expander Header="{Binding Path=DispName}"> 
            <ListView ItemsSource="{Binding Path=Rows}" 
               HorizontalAlignment="Left" BorderThickness="2" BorderBrush="Purple"> 
             <ListView.ItemTemplate > 
              <DataTemplate> 
               <CheckBox Width="125" IsChecked="{Binding Path=On}"> 
                <TextBlock Text="{Binding Path=StrValue}" TextWrapping="Wrap"/> 
               </CheckBox> 
              </DataTemplate> 
             </ListView.ItemTemplate> 
            </ListView> 
           </Expander> 
          </DataTemplate> 
         </ListView.ItemTemplate> 
        </ListView> 
       </Expander> 
       <Expander IsExpanded="False" Header="Exp2" BorderThickness="2" BorderBrush="Green"> 
        <ListView ItemsSource="{Binding Path=List2}" 
           HorizontalAlignment="Left" BorderThickness="2" BorderBrush="Orange"> 
         <ListView.ItemsPanel> 
          <ItemsPanelTemplate> 
           <StackPanel/> 
          </ItemsPanelTemplate> 
         </ListView.ItemsPanel> 
         <ListView.ItemTemplate > 
          <DataTemplate> 
           <Expander Header="{Binding Path=DispName}"> 
            <ListView ItemsSource="{Binding Path=Rows}" 
               HorizontalAlignment="Left" BorderThickness="2" BorderBrush="Purple"> 
             <ListView.ItemTemplate > 
              <DataTemplate> 
               <CheckBox Width="125" IsChecked="{Binding Path=On}"> 
                <TextBlock Text="{Binding Path=StrValue}" TextWrapping="Wrap"/> 
               </CheckBox> 
              </DataTemplate> 
             </ListView.ItemTemplate> 
            </ListView> 
           </Expander> 
          </DataTemplate> 
         </ListView.ItemTemplate> 
        </ListView> 
       </Expander> 
      </StackPanel> 
     </ScrollViewer> 
    </Grid> 
</Window> 

namespace ListViewJump 
{ 
    public partial class MainWindow : Window 
    { 
     private List<ListItem> list1 = new List<ListItem>(); 
     private List<ListItem> list2 = new List<ListItem>(); 
     public MainWindow() 
     { 
      this.DataContext = this; 
      for (int i = 1; i < 10; i++) 
      { 
       List<ListItemRow> lr1 = new List<ListItemRow>(); 
       List<ListItemRow> lr2 = new List<ListItemRow>(); 
       for (int j = 1; j < 100; j++) 
       { 
        lr1.Add(new ListItemRow("Row Row Row Row Row Row" + j.ToString())); 
        lr2.Add(new ListItemRow("Rwo Rwo Rwo Rwo Rwo Rwo" + j.ToString())); 
       } 
       list1.Add(new ListItem("one " + i.ToString(), lr1)); 
       list2.Add(new ListItem("two " + i.ToString(), lr2)); 
      } 
      InitializeComponent();       
     } 
     public List<ListItem> List1 { get { return list1; } } 
     public List<ListItem> List2 { get { return list2; } } 
    } 
    public class ListItem 
    { 
     private string dispName; 
     private List<ListItemRow> rows; 
     public string DispName { get { return dispName; } } 
     public List<ListItemRow> Rows { get { return rows; } } 
     public ListItem(String DispName, List<ListItemRow> Rows) { dispName = DispName; rows = Rows; } 
    } 
    public class ListItemRow 
    { 
     private string strValue; 
     private bool on = false; 
     public string StrValue { get { return strValue; } } 
     public bool On 
     { 
      get { return on; } 
      set { on = value; } 
     } 
     public ListItemRow(String StrValue) { strValue = StrValue; } 
    } 
} 

我認爲這裏有兩個錯誤。
控件不縮小,點擊獲取處理兩次。
我收縮會增加開銷,但仍然爲什麼不是一個選項。

回答

2

你用你的榜樣玩了一段時間,但我最終意識到行爲的根源是什麼,以及要去尋找什麼。

我覺得您遇到點擊時由您的CheckBox獲得焦點的問題,並提出一個RequestBringIntoView事件,這將從根本上導致ScrollViewer踢包含控制你的CheckBox進入「正確」的地方。這個機制解釋了這個答案:Stop WPF ScrollViewer automatically scrolling to perceived content

如果該滾動發生在您點擊CheckBox時,它會從光標下移出,然後您可以取消點擊鼠標(您可以證明在發生問題時按住鼠標,然後移動您的鼠標將鼠標懸停在有問題的CheckBox上,然後釋放它)。

您可以創建爲RequestBringIntoView事件一個簡單的事件處理程序和您的DataTemplate內與CheckBox使用它,並使用Handled財產抑制的情況下,所以它不會傳播任何進一步的(下面的工作對我來說)。

XAML:

<DataTemplate> 
    <CheckBox Width="125" IsChecked="{Binding Path=On}" RequestBringIntoView="RequestBringIntoViewSuppressor"> 
     <TextBlock Text="{Binding Path=StrValue}" TextWrapping="Wrap"/> 
    </CheckBox> 
</DataTemplate> 

C#:

private void RequestBringIntoViewSuppressor(object sender, RequestBringIntoViewEventArgs e) 
{ 
    e.Handled = true; 
} 

CheckBox現在將不再正確地把自己變成看法,如果它是稍微偏離屏幕,但它不會意外跳了,如果需要,您可以進一步定製處理程序。

+0

謝謝。我還需要在ListView中的Expander上使用相同的東西。一部分不在屏幕上的項目比我的要好得多。 – Paparazzi

+0

啊,這很有道理。祝你好運= D – Chris

+0

我要求從社區wiki中獲得此信息,以便獲得信用。它去了維基,因爲我編了很多次,但基本的問題沒有改變。 – Paparazzi