2011-04-05 5 views
1

CanBox에서 ListBox에있는 UserControls를 가지고 있습니다. 그런 다음 DraggableExtender (Dragging an image in WPF)를 사용하여 캔버스에서 드래그 할 수있는 UserControl을 만들었습니다.캔버스의 ListBox에서 WPF Draggable UserControls

그러나 ItemsControl에서 ListBox로 변경 한 이후로 컨트롤을 선택 가능하게 만들기 위해 끌기 작업이 정말 좋지 않습니다. 예를 들어 다른 컨트롤 위에 컨트롤을 끌면 다른 컨트롤에 포커스가 맞추어지고 끌기에 집착합니다. 또한 캔버스 밖으로 마우스를 움직이면 UserControl은 가장자리에 붙어서 CaptureMouse가 작동하지 않는 것처럼 포커스를 끌어 당깁니다. (이 ItemsControl에 전에이 일 때)

목록 상자는 다음과 같습니다 : 나는 해결책을 찾기 위해 노력했습니다

public class DraggableExtender : DependencyObject 
    { 
     public static readonly DependencyProperty CanDragProperty = 
      DependencyProperty.RegisterAttached("CanDrag", typeof(bool), typeof(DraggableExtender), 
      new UIPropertyMetadata(false, OnChangeCanDragProperty)); 

     private static bool isDragging = false; 
     private static Point offset; 

     public static void SetCanDrag(UIElement element, bool o) 
     { 
      element.SetValue(CanDragProperty, o); 
     } 

     public static bool GetCanDrag(UIElement element, bool o) 
     { 
      return (bool)element.GetValue(CanDragProperty); 
     } 

     private static void OnChangeCanDragProperty(DependencyObject d, DependencyPropertyChangedEventArgs e) 
     { 
      UIElement element = d as UIElement; 
      if (element == null) return; 

      if (e.NewValue != e.OldValue) 
      { 
       if ((bool)e.NewValue) 
       { 
        element.PreviewMouseDown += element_PreviewMouseDown; 
        element.PreviewMouseUp += element_PreviewMouseUp; 
        element.PreviewMouseMove += element_PreviewMouseMove; 
       } 
       else 
       { 
        element.PreviewMouseDown -= element_PreviewMouseDown; 
        element.PreviewMouseUp -= element_PreviewMouseUp; 
        element.PreviewMouseMove -= element_PreviewMouseMove; 
       } 
      } 
     } 

     private static void element_PreviewMouseDown(object sender, MouseButtonEventArgs e) 
     { 
      FrameworkElement element = sender as FrameworkElement; 
      if (element == null) return; 
      Debug.WriteLine(element); 

      isDragging = true; 
      element.CaptureMouse(); 
      offset = e.GetPosition(element); 
     } 

     private static void element_PreviewMouseMove(object sender, MouseEventArgs e) 
     { 
      if (!isDragging) return; 

      FrameworkElement element = sender as FrameworkElement; 
      if (element == null) return; 

      Canvas canvas = element.FindAncestor<Canvas>(); 
      if (canvas == null) return; 

      Point mousePoint = e.GetPosition(canvas); 

      mousePoint.Offset(-offset.X, -offset.Y); 

      element.SetValue(Canvas.LeftProperty, mousePoint.X); 
      element.SetValue(Canvas.TopProperty, mousePoint.Y); 
     } 

     private static void element_PreviewMouseUp(object sender, MouseButtonEventArgs e) 
     { 
      FrameworkElement element = sender as FrameworkElement; 
      if (element == null) return; 
      element.ReleaseMouseCapture(); 
      isDragging = false; 
     } 
} 

하지만 :

<ListBox ItemsSource="{Binding Components}" SelectedItem="{Binding SelectedItem}" Background="Transparent"> 
      <ListBox.ItemsPanel> 
       <ItemsPanelTemplate> 
        <Canvas ClipToBounds="True" Height="{Binding CurrentProject.Height, Converter={StaticResource SizeConverter}}" 
          Width="{Binding CurrentProject.Width, Converter={StaticResource SizeConverter}}" 
          HorizontalAlignment="Left" VerticalAlignment="Top"> 
         <Canvas.Background> 
          <SolidColorBrush Color="{DynamicResource {x:Static SystemColors.WindowFrameColorKey}}"/> 
         </Canvas.Background> 
        </Canvas> 
       </ItemsPanelTemplate> 
      </ListBox.ItemsPanel> 
      <ListBox.ItemContainerStyle> 
       <Style TargetType="{x:Type ListBoxItem}"> 
        <Setter Property="HorizontalAlignment" Value="Stretch" /> 
        <Setter Property="Background" Value="Transparent" /> 
        <Setter Property="Template"> 
         <Setter.Value> 
          <ControlTemplate TargetType="{x:Type ListBoxItem}"> 
           <Grid> 
            <Border Background="{TemplateBinding Background}" /> 
            <ContentPresenter/> 
           </Grid> 
           <ControlTemplate.Triggers> 
            <MultiTrigger> 
             <MultiTrigger.Conditions> 
              <Condition Property="IsMouseOver" Value="True" /> 
              <Condition Property="IsSelected" Value="False"/> 
             </MultiTrigger.Conditions> 
             <Setter Property="Background" Value="#8868D5FD" /> 
            </MultiTrigger> 
            <Trigger Property="IsSelected" Value="True"> 
             <Setter Property="Background" Value="#4468D5FD" /> 
            </Trigger> 
           </ControlTemplate.Triggers> 
          </ControlTemplate> 
         </Setter.Value> 
        </Setter> 
        <Setter Property="Utils:DraggableExtender.CanDrag" Value="True" /> 
        <Setter Property="Canvas.Top" Value="{Binding Path=Conveyor.Y, Converter={StaticResource SizeConverter},Mode=TwoWay}" /> 
        <Setter Property="Canvas.Left" Value="{Binding Path=Conveyor.X, Converter={StaticResource SizeConverter},Mode=TwoWay}" /> 
       </Style> 
      </ListBox.ItemContainerStyle> 
     </ListBox> 

내 DraggableExtender은 다음과 같습니다 지금까지 나는 실패했다. 왜 이런 일이 일어나고 어떻게 해결할 수 있을지 아무도 모른다.

답변

0

이 문제를 해결하는 방법이나 해결 방법을 찾는 방법에 대해 알아낼 수있었습니다. 문제는 ListBox가 선택 코드 내에서 마우스를 캡처한다는 것입니다. 그래서 내가 변경 한 것은 e.Handled = true를 추가하여 ListBox가 이벤트를 가져 오지 않아서 mousecapture를 오버라이드하는 것입니다. 이것은 선택 메커니즘을 사용할 수 없게 만들었지 만 해결 방법은이 코드를 MouseRight 이벤트 만 듣기로 옮겼습니다. 이는 내가 leftclick 할 때 내가 선택하고 드래그 할 수있는 rightclick을 의미합니다.

private static void element_PreviewMouseDown(object sender, MouseButtonEventArgs e) 
     { 
      FrameworkElement element = sender as FrameworkElement; 
      if (element == null) return; 
      Debug.WriteLine(element); 

      isDragging = true; 
      element.CaptureMouse(); 
      offset = e.GetPosition(element); 
      e.Handled = true; 
     }