2009-05-04 34 views
41

Tôi có một ListBox trong cửa sổ wpf của mình liên kết với một ObervableCollection. Tôi muốn mở trình duyệt nếu ai đó nhấp vào một phần tử của ListBox (giống như một liên kết). Ai đó có thể nói cho tôi cách làm cái này không? Tôi tìm thấy một cái gì đó với listboxviews, nó chỉ làm việc theo cách này hoặc là có một cách bằng cách chỉ sử dụng ListBox?Nhấp đúp vào mục ListBox để mở trình duyệt

Yours

Sebastian

Trả lời

81

Bạn có thể thêm một phong cách để ListBox.ItemContainerStyle, và thêm một EventSetter có:

<ListBox> 
    .... 
    <ListBox.ItemContainerStyle> 
     <Style TargetType="{x:Type ListBoxItem}" BasedOn="{StaticResource {x:Type ListBoxItem}}"> 
      <EventSetter Event="MouseDoubleClick" Handler="ListBoxItem_MouseDoubleClick"/> 
     </Style> 
    </ListBox.ItemContainerStyle> 
</ListBox> 

ListBoxItem_MouseDoubleClick là một phương pháp trong mã của bạn đằng sau với chữ ký chính xác cho MouseDoubleClick.

+1

Cảm ơn. Điều này giải quyết vấn đề của tôi quá. Một followup: Điều này làm việc rất tốt trong ứng dụng đang chạy, nhưng nó lại thiết kế studio trực quan (không phải là một showstopper, nhưng là một kích thích). Tôi không xác định rõ ràng một kiểu ListBoxItem trong tài nguyên ứng dụng, vì vậy BaseOn sẽ thất bại trong thời gian thiết kế. Tuy nhiên, tôi có một thư viện theming (WPFTheme) định nghĩa tài nguyên này khi chạy. Nếu tôi định nghĩa một tài nguyên tĩnh, nó sẽ xóa bỏ một tài nguyên động, theo chủ đề. Bất cứ suy nghĩ nào về cách tôi có thể làm cho cả hai cùng chơi tốt đẹp? – el2iot2

+1

Sau khi thử nghiệm nhiều hơn một chút, tôi đã tìm ra ... Tôi chỉ tham chiếu xaml của chủ đề trong thuộc tính mergedresource: el2iot2

+0

khá thú vị nhưng nếu bạn đã định nghĩa ItemContainerStyle trong ResourceDictionary thì sao? – Oliver

10

Tôi muốn giải quyết vấn đề này mà không cần xử lý sự kiện double click listBoxItem trong mã phía sau và tôi không muốn ghi đè kiểu listBoxItem (hoặc xác định kiểu ghi đè ở vị trí đầu tiên). Tôi muốn chỉ cần bắn một lệnh khi listBox được doubleclicked.

Tôi tạo ra một tài sản gắn liền như vậy (mã là rất cụ thể, nhưng bạn có thể khái quát nó như là bắt buộc):

public class ControlItemDoubleClick : DependencyObject { 
public ControlItemDoubleClick() 
{ 

} 

public static readonly DependencyProperty ItemsDoubleClickProperty = 
    DependencyProperty.RegisterAttached("ItemsDoubleClick", 
    typeof(bool), typeof(Binding)); 

public static void SetItemsDoubleClick(ItemsControl element, bool value) 
{ 
    element.SetValue(ItemsDoubleClickProperty, value); 

    if (value) 
    { 
     element.PreviewMouseDoubleClick += new MouseButtonEventHandler(element_PreviewMouseDoubleClick); 
    } 
} 

static void element_PreviewMouseDoubleClick(object sender, MouseButtonEventArgs e) 
{ 
    ItemsControl control = sender as ItemsControl; 

    foreach (InputBinding b in control.InputBindings) 
    { 
     if (!(b is MouseBinding)) 
     { 
      continue; 
     } 

     if (b.Gesture != null 
      && b.Gesture is MouseGesture 
      && ((MouseGesture)b.Gesture).MouseAction == MouseAction.LeftDoubleClick 
      && b.Command.CanExecute(null)) 
     { 
      b.Command.Execute(null); 
      e.Handled = true; 
     } 
    } 
} 

public static bool GetItemsDoubleClick(ItemsControl element) 
{ 
    return (bool)element.GetValue(ItemsDoubleClickProperty); 
} 

}

tôi sau đó tuyên bố ListBox của tôi với các tài sản gắn liền và tôi lệnh mục tiêu:

<ListBox ItemsSource="{Binding SomeItems}" 
    myStuff:ControlItemDoubleClick.ItemsDoubleClick="true"> 
<ListBox.InputBindings> 
    <MouseBinding MouseAction="LeftDoubleClick" Command="MyCommand"/> 
</ListBox.InputBindings> 
</ListBox> 

Hy vọng điều này sẽ hữu ích.

+0

nhưng sẽ không cháy nếu họ nhấp đúp vào thanh cuộn? Hoặc bất kỳ padding giữa ListBoxItems? –

+0

Có, nó sẽ kích hoạt nếu bạn nhấp đúp vào bất kỳ đâu trong hộp danh sách. Vẫn còn cho tôi đó là một giải pháp tốt, tôi thích nó mà nó không có mã phía sau. Thay đổi các tham số lệnh cho b.Command.CanExecute (null) và Execute (null) từ null thành b.CommandParameter. – HeWillem

4

tôi sử dụng biểu SDK 4,0

xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 

<i:Interaction.Triggers> 
    <i:EventTrigger EventName="MouseDoubleClick" SourceName="CaravanasListBox"> 
    <i:InvokeCommandAction Command="{Binding AccionesToolbarCommand}" CommandParameter="{x:Static local:OpcionesBarra.MostrarDetalle}" /> 
    </i:EventTrigger> 
</i:Interaction.Triggers> 

Jaimir G.

+0

Nếu điều này được gắn vào hộp danh sách, sau đó nó sẽ kích hoạt nếu bạn nhấp đúp vào bất kỳ phần nào của hộp danh sách, bao gồm thanh cuộn gây phiền nhiễu đáng kinh ngạc với danh sách dài. Và listboxitem dường như không có sự kiện MouseDoubleClick. – Sinaesthetic

6

Tôi đã cập nhật giải pháp Andrews để giải quyết vấn đề với bắn thực hiện lệnh nếu nhấn đúp chuột bất cứ nơi nào trong hộp danh sách:

public class ControlDoubleClick : DependencyObject 
{ 
    public static readonly DependencyProperty CommandProperty = 
     DependencyProperty.RegisterAttached("Command", typeof(ICommand), typeof(ControlDoubleClick), new PropertyMetadata(OnChangedCommand)); 

    public static ICommand GetCommand(Control target) 
    { 
     return (ICommand)target.GetValue(CommandProperty); 
    } 

    public static void SetCommand(Control target, ICommand value) 
    { 
     target.SetValue(CommandProperty, value); 
    } 

    private static void OnChangedCommand(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     Control control = d as Control; 
     control.PreviewMouseDoubleClick += new MouseButtonEventHandler(Element_PreviewMouseDoubleClick); 
    } 

    private static void Element_PreviewMouseDoubleClick(object sender, MouseButtonEventArgs e) 
    { 
     Control control = sender as Control; 
     ICommand command = GetCommand(control); 

     if (command.CanExecute(null)) 
     { 
      command.Execute(null); 
      e.Handled = true; 
     } 
    } 
} 

Và trong XAML, khai báo cho ListBox là:

<ListBox ItemsSource="{Binding MyItemsSource, Mode=OneWay}">      
     <ListBox.ItemContainerStyle> 
        <Style>        
         <Setter Property="behaviours:ControlDoubleClick.Command" Value="{Binding DataContext.MyCommand, 
            RelativeSource={RelativeSource FindAncestor, 
            AncestorType={x:Type UserControl}}}"/> 
        </Style> 
    </ListBox.ItemContainerStyle> 
</ListBox> 
+0

Cảm ơn, điều này làm việc tốt cho tôi. –

+1

câu trả lời hay nhất ở đây! – JokerMartini

+1

Đây là giải pháp tôi đã chọn độc lập sau khi thử một vài tùy chọn, nhưng tôi đã thay đổi chút ràng buộc: Tôi đã đặt 'UserControl' một' Name', xóa tìm kiếm 'RelativeSource' và thêm' ElementName' vào vị trí của nó cái tên tôi đưa ra sự kiểm soát. Kết quả là như nhau, nhưng nó có thể tiết kiệm một số không gian/thời gian chạy cho những người có rất nhiều tài liệu tham khảo để kiểm soát. – Dan

Các vấn đề liên quan