2011-03-31 35 views
1

我寫了一個DragBehavior,它基於一般的拖放示例。雖然這是在沒有行爲的情況下工作的,但當我將代碼放入行爲中時,它並不動。Rx DragBehavior - >爲什麼我的元素不移動

行爲:

public class DragBehavior : Behavior<UIElement> 
    { 

     protected override void OnAttached() 
     { 
      Window mainCanvas = Application.Current.MainWindow; 

      var mouseDown = from evt in AssociatedObject.GetMouseLeftButtonDown() 
           select evt.EventArgs.GetPosition(mainCanvas); 
      var mouseUp = from evt in AssociatedObject.GetMouseLeftButtonUp() 
          select evt.EventArgs.GetPosition(mainCanvas); 
      var mouseMove = from evt in AssociatedObject.GetMouseMove() 
          select evt.EventArgs.GetPosition(mainCanvas); 

      var q = from start in mouseDown 
        from delta in mouseMove.StartWith(start).TakeUntil(mouseUp) 
        .Let(mm => mm.Zip(mm.Skip(1),(pre,cur) => 
         new{ X= cur.X - pre.X, Y= cur.Y - pre.Y})) 
         select delta; 

      q.Subscribe(value => 
      { 
       Canvas.SetLeft(AssociatedObject, Canvas.GetLeft(AssociatedObject) + value.X); 
       Canvas.SetTop(AssociatedObject, Canvas.GetTop(AssociatedObject) + value.Y); 
      }); 

     } 
    } 

輔助方法:

public static IObservable<IEvent<MouseEventArgs>> GetMouseMove(
      this UIElement inputElement) 
     { 

      return Observable.FromEvent(
       (EventHandler<MouseEventArgs> h) => new MouseEventHandler(h), 
       h => inputElement.MouseMove += h, 
       h => inputElement.MouseMove -= h); 
     } 

     public static IObservable<IEvent<MouseButtonEventArgs>> 
      GetMouseLeftButtonDown(this UIElement inputElement) 
     { 
      return Observable.FromEvent(
       (EventHandler<MouseButtonEventArgs> genericHandler) => 
        new MouseButtonEventHandler(genericHandler), 
          h => inputElement.MouseLeftButtonDown += (h), 
          h => inputElement.MouseLeftButtonDown -= (h)); 
     } 

     public static IObservable<IEvent<MouseButtonEventArgs>> 
      GetMouseLeftButtonUp(this UIElement inputElement) 
     { 
      return Observable.FromEvent(
       (EventHandler<MouseButtonEventArgs> genericHandler) => 
        new MouseButtonEventHandler(genericHandler), 
          h => inputElement.MouseLeftButtonUp += h, 
          h => inputElement.MouseLeftButtonUp -= h); 
     }} 


    <Window x:Class="DesignerTest.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:vm="clr-namespace:DesignerTest.ViewModels" 
    xmlns:h="clr-namespace:DesignerTest.Helpers" 
    xmlns:e="http://schemas.microsoft.com/expression/2010/interactivity" 
    Title="MainWindow" Height="350" Width="525"> 
<Window.DataContext> 
    <vm:WindowViewModel /> 
</Window.DataContext> 
<Grid> 
    <ItemsControl ItemsSource="{Binding Path=Shapes}"> 
    <ItemsControl.ItemsPanel> 
     <ItemsPanelTemplate> 
      <Canvas /> 
     </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 
     <ItemsControl.ItemTemplate> 
      <DataTemplate> 
       <StackPanel> 
        <e:Interaction.Behaviors> 
         <h:DragBehavior /> 
        </e:Interaction.Behaviors> 
        <TextBlock Text="{Binding X}" /> 
       </StackPanel> 
      </DataTemplate> 
     </ItemsControl.ItemTemplate> 
    <ItemsControl.ItemContainerStyle> 
      <Style TargetType="ContentPresenter"> 
      <Setter Property="Canvas.Left" Value="{Binding Path=X,Mode=TwoWay}" /> 
      <Setter Property="Canvas.Top" Value="{Binding Path=Y,Mode=TwoWay}" /> 
     </Style> 
    </ItemsControl.ItemContainerStyle> 
    </ItemsControl> 
</Grid> 

回答

2

是代碼實際運行?添加「當打」斷點OnAttached和你的訂閱關閉描繪出什麼atually發生

此外,在您的實現的一些註釋:

  • 我建議創建一個MutableDisposable私有成員和分配返回值爲SubscribeDisposable屬性。這將允許您取消訂閱OnDetached
  • 中的所有內容因爲TakeUntil不要求序列具有相同類型,所以不需要選擇MouseUp事件的位置。

編輯:我認爲問題是,StackPanel要添加的不是Canvas本身的畫布屬性實際上是對ItemContainerTemplateContentPresenter)元素的子元素。您應該在行爲的OnAttached方法中行走樹,或者定義您自己的ItemContainerTemplate,然後將行爲附加到ContentPresenter

+0

代碼在編譯,但如預期,這就是爲什麼我問的沒有運行。我應該如何檢查斷點。座標實際上是由linq2events查詢結果拾取的,但元素沒有移動我有點失落.. – silverfighter 2011-03-31 21:44:43

+0

@silverfighter - 我想我知道這個問題。查看我的更新。 – 2011-04-01 06:37:20

3

更改模板有點... MB這將幫助你..

<DataTemplate> 
    <!-- change background to transparent -->   
    <StackPanel Background="Transparent">    
     <e:Interaction.Behaviors>       
      <h:DragBehavior />      
     </e:Interaction.Behaviors> 
     <!-- Prevent yout textBlock from capturing mouse events -->  
     <!-- by setting is HitTestVisible to false --> 
     <TextBlock Text="{Binding X}" IsHitTestVisible="False" />     
    </StackPanel>    
</DataTemplate> 
+2

+1爲了向我介紹'IsHitTestVisible' – 2011-04-01 08:15:00