Beispiel #1
0
        FrameworkElement GetAdornerRoot(DependencyObject d)
        {
            var ret = VisualTreeHelperExtension.Ancestors(d)
                      .OfType <FrameworkElement>()
                      .Reverse()
                      .FirstOrDefault(x => AdornerLayer.GetAdornerLayer(x) != null);

            return(ret);
        }
Beispiel #2
0
        // MouseEnter/Leaveの挙動とDragEnter/Leaveの挙動が違う...マウスキャプチャしてる関係と思われる
        // - トンネルしていくイベントの回数が違う Dragはいちいち構成要素のコントロールに対して発生する
        // - DragEnter/Leaveは1つのコントロールしかEnter状態にならない?(必ずLeaveしてから次にEnterしている)
        //     MouseEnter/Leaveは複数のコントロールにEnterした状態になる
        // - スクロールの中にコントロールがある場合、DragEnter/Leaveを発生させずにBorderに出入りできてしまう
        //     中に入った時点でBorderからはLeaveしてるから?

        // じゃぁどうすればいいのか
        // DragOverは発火し続けるみたい
        //   未表示ならShowIndicator表示
        //   未起動なら0.1秒タイマを起動
        //   最後のDragOver時刻を更新
        // => Tickで最後のDragOver時刻から0.1秒経過していたら閉じる

        private void OnPreviewDragOver(object sender, DragEventArgs e)
        {
            LastDragOver = DateTime.Now;

            if (Timer == null)
            {
                Timer          = new DispatcherTimer();
                Timer.Interval = TimeSpan.FromSeconds(0.05);
                Timer.Tick    += Timer_Tick;
                Timer.Start();

                System.Diagnostics.Debug.WriteLine(
                    "DropBehavior.DragOver START ({0}, {1}, {2})",
                    sender.GetType().Name,
                    e.Source.GetType().Name,
                    e.OriginalSource.GetType().Name
                    );

                // ここでDrop対象かどうか判定する
                if (e.Data.GetDataPresent(DataType?.ToString() ?? "test"))
                {
                    IsAcceptable = true;
                }
                else
                {
                    IsAcceptable = false;
                }

                // 自分のindicatorを出したい時、
                //   まず親に表示中のやつがいないかチェックして、いれば隠す
                //   それから自分を表示

                if (IsAcceptable)
                {
                    var ancestors = VisualTreeHelperExtension
                                    .AncestorsOrSelf(AssociatedObject)
                                    .Behaviors()
                                    .OfType <DropBehavior>()
                                    .Where(b => b != this)
                                    .Where(b => b.IsAcceptable)
                    ;

                    foreach (var ancestor in ancestors)
                    {
                        ancestor.AddIntercepter(this);
                    }

                    this.ShowIndicator();
                }
            }
        }
        private void OnDragDelta(object sender, DragDeltaEventArgs e)
        {
            if (Target == null)
            {
                return;
            }

            // itemscontrolのitemscontainerを探す方法がよくわからない
            var container = VisualTreeHelperExtension
                            .Ancestors(AssociatedObject)
                            .OfType <UIElement>()
                            .TakeUntilButNotIncluding(x => x is Canvas)
                            .LastOrDefault();

            if (container == null)
            {
                return;
            }

            Canvas.SetLeft(container, Math.Max(0, Canvas.GetLeft(container) + e.HorizontalChange));
            Canvas.SetTop(container, Math.Max(0, Canvas.GetTop(container) + e.VerticalChange));
        }
Beispiel #4
0
        private void Timer_Tick(object sender, EventArgs e)
        {
            // DragOverが一定期間発生していなければ、マウスが外れたと判定して自分のAdornerを隠す
            if (DateTime.Now > LastDragOver + TimeSpan.FromSeconds(0.1))
            {
                Timer.Stop();
                Timer.Tick -= Timer_Tick;
                Timer       = null;

                IsAcceptable = false;

                System.Diagnostics.Debug.WriteLine(
                    "{0} DropBehavior.DragOver FINISHED",
                    DateTime.Now.ToString("HH:mm:ss.fff")
                    );

                // 自分のindicatorを隠す場合、
                //   まず自分を隠す
                //   親にドロップ可能なやつがいないかチェックして、いれば表示

                if (IsShowAdorner)
                {
                    this.HideIndicator();

                    var ancestors = VisualTreeHelperExtension
                                    .AncestorsOrSelf(AssociatedObject)
                                    .Behaviors()
                                    .OfType <DropBehavior>()
                                    .Where(b => b != this)
                    ;

                    foreach (var ancestor in ancestors)
                    {
                        ancestor.RemoveIntercepter(this);
                    }
                }
            }
        }
 private void AssociatedObject_Loaded(object sender, RoutedEventArgs e)
 {
     Scroll = VisualTreeHelperExtension.DescendantsOrSelf(AssociatedObject).OfType <ScrollViewer>().First();
 }