2010-01-05 61 views
1

如何讓ListBox,Canvas和Thumb一起工作?如何讓ListBox,Canvas和Thumb一起工作?

我正在嘗試重用列表框的選擇邏輯與包含可拖動的拇指的畫布。

不幸的是,Thumb似乎處理了鼠標事件,因此單擊Thumb時不會選中該項目。

我希望這些元素可以一起工作,而不訴諸程序代碼中的解決方法。如果有人知道這是可能的還是怎麼做的,請告訴我。

代碼示例如下。

在XAML我定義列表框,並指定一個Canvas作爲ItemsPanel:

<Window x:Class="ListBoxCanvasThumb.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="Window1" Height="300" Width="300" 
    Loaded="Window_Loaded" 
    > 
    <Grid> 
     <ListBox 
      x:Name="listBox" 
      > 
      <ListBox.ItemsPanel> 
       <ItemsPanelTemplate>     
        <Canvas /> 
       </ItemsPanelTemplate> 
      </ListBox.ItemsPanel> 
     </ListBox> 
    </Grid> 
</Window> 

在Loaded事件處理程序創建一個可拖動的拇指,在ListBoxItem中把它包起來,設置畫布的當前位置和然後將其添加到列表框:

private void Window_Loaded(object sender, RoutedEventArgs e) 
{ 
    Thumb t = new Thumb(); 
    t.Width = 10; 
    t.Height = 10; 
    t.DragDelta += new DragDeltaEventHandler(thumb_DragDelta); 

    ListBoxItem i = new ListBoxItem(); 
    Canvas.SetLeft(i, 10); 
    Canvas.SetTop(i, 10); 
    i.Content = t; 

    listBox.Items.Add(i); 
} 

在DragDelta事件處理我更新的項目在畫布中的位置:

void thumb_DragDelta(object sender, DragDeltaEventArgs e) 
{ 
    ListBoxItem i = (ListBoxItem)((Thumb)sender).Parent; 
    Canvas.SetLeft(i, Canvas.GetLeft(i) + e.HorizontalChange); 
    Canvas.SetTop(i, Canvas.GetTop(i) + e.VerticalChange); 
} 

回答

3

爲此,您的Thumb控制的使用是不是真的給你買所有的東西,它在幾個方面與你是什麼衝突試圖去做。我會擺脫它。

這是非常簡單的只是攔截按下鼠標,鼠標移動,讓您的物品拖動沒有Thumb,和鼠標向上事件:

  • 在按下鼠標,設置一個「拖」標誌,請注意當前位置和捕捉鼠標
  • 在鼠標移動時,如果「拖動」爲真,則更新Canvas.Left和Canvas.Top,由控件上的鼠標位置與原始位置之間的差異
  • 在鼠標上方,清除「拖動」標誌並清除鼠標捕捉

通過這樣做Thumb將不會攔截鍵盤和鼠標的點擊並搞亂您的ListBox

+0

這對我不起作用。仍然吞下點擊並且列表框不會被選中。你能修復它@AshleyDavis? – Carlo 2014-04-30 00:54:31

1

我不知道這是否會滿足您的要求不使用的程序代碼,因爲顯然你已經是(或者是這只是一個例子再現?)

無論如何,一個處理程序添加到ListBoxItemPreviewMouseDown和選擇項目有:

i.PreviewMouseDown += new MouseButtonEventHandler(LBI_PreviewMouseDown); 

void LBI_PreviewMouseDown(object sender, MouseButtonEventArgs e) 
{ 
    var lbi = (ListBoxItem)sender; 
    lbi.IsSelected = true; 
    lbi.Focus(); 
} 
+0

感謝您的回答,但這基本上是我已經這樣做的方式。問題在於我想做的比這更多。例如,以這種方式實現多選和鍵盤輸入(左鍵和右鍵改變選擇)會產生更多的程序代碼。我開始這樣做,但發現自己認爲必須有更好的方式! – 2010-01-05 10:37:48

+0

順便說一句,我在上面的Window_Loaded中使用的過程代碼只是爲了說明問題,我的真實代碼數據綁定了一個對象列表到ItemSource並使用DataTemplate來填充ListBox。 – 2010-01-05 10:38:19

1

你可以嘗試拇指移動到ListBoxItem的模板,並使用拇指的焦點狀態觸發選擇。 Thumb默認情況下不可對焦,但您可以將其打開。

  <ListBox.ItemContainerStyle> 
      <Style TargetType="{x:Type ListBoxItem}"> 
       <Setter Property="Canvas.Left" Value="10" /> 
       <Setter Property="Canvas.Top" Value="10" /> 
       <Setter Property="Template"> 
        <Setter.Value> 
         <ControlTemplate TargetType="{x:Type ListBoxItem}"> 
          <Border x:Name="Bd" ...> 
           <DockPanel> 
            <Thumb x:Name="dragger" DockPanel.Dock="Top" 
              Width="50" Height="20" Focusable="True"/> 
            <ContentPresenter/> 
           </DockPanel> 
          </Border> 
          <ControlTemplate.Triggers> 
           <Trigger SourceName="dragger" Property="IsFocused" Value="True"> 
            <Setter Property="IsSelected" Value="True" /> 
           </Trigger> 

...

相關問題