0

UIElement(rectangle/area/bounds) で sを見つける必要があります。

私は次のことをやっています:

  • マウスダウンを開始位置として登録します。
  • マウスアップ位置を登録します。
  • ここで、開始位置と終了位置の間の長方形で ll (ボタン、テキストボックスなど) を見つける必要があります。

私はmsdnでHitTestアプローチを見つけましたが、それは一点だけです。作成された四角形のすべてのポイントを歩くと、パフォーマンスが低下すると思います。

http://msdn.microsoft.com/en-us/library/ms752097.aspx

MVVM パターンに基づく私のコード:

private ObservableCollection<UIElementViewModel> wells;   
private Point stratPoint; // Mouse down
public ICommand MouseUpRightCommand
{
  get
  {
    if (this.mouseUpRightCommand == null)
    {
      this.mouseUpRightCommand = new RelayCommands(
        param =>
       {
          if (param is MouseButtonEventArgs)
          {
            var e = (param as MouseButtonEventArgs);

            //Set the end point
            endPosition = e.GetPosition(((ItemsControl)e.Source));

            // for example, here I want to find all controls(UIElements) in the
            // founded rectangle of stratPoint and endPosition.

          }
        });
    }

    return this.mouseUpRightCommand;
  }
}

他のアイデアやより良いアプローチはありますか?

ありがとう

4

3 に答える 3

3

プロパティを使用するために、の代わりにFrameworkElement(を拡張する)を使用しますUIElementUIElementActualWidthActualHeight

次に、数学を行う静的クラスを作成しますMouseUtils

それらの静的フィールドで

    private static double _dContainerTop;
    private static double _dContainerBottom;
    private static double _dContainerLeft;
    private static double _dContainerRight;
    private static double _dCursorTop;
    private static double _dCursorLeft;
    private static double _dCursorRight;
    private static double _dCursorBottom;

そしてそれらの静的メソッド

    private static void FindValues(FrameworkElement element, Visual rootVisual)
    {
        var containerTopLeft = container.TransformToAncestor(rootVisual).Transform(new Point(0, 0));

        _dContainerTop = containerTopLeft.Y;
        _dContainerBottom = _dContainerTop + container.ActualHeight;
        _dContainerLeft = containerTopLeft.X;
        _dContainerRight = _dContainerLeft + container.ActualWidth;

    }

    public static bool IsElementUnderRectCursor(FrameworkElement element, Point startPoint, Point endPoint, Visual rootVisual)
    {
       _dCursorTop=Math.Min(startPoint.Y, endPoint.Y);
       _dCursorBottom=Math.Max(startPoint.Y, endPoint.Y);
       _dCursorLeft=Math.Min(startPoint.X, endPoint.X);
       _dCursorRight=Math.Max(startPoint.X, endPoint.X);

        FindValues(container, rootVisual);
        if (_dContainerTop < _dCursorTop|| _dCursorBottom< _dContainerBottom )
        {
            return false;
        }
        if (_dContainerLeft < _dCursorLeft|| _dContainerRight < _dCursorRight)
        {
            return false;
        }
        return true;
    }

Rootvisualたとえば、あなたのウィンドウです。

次に、ループしObservableCollection<FrameworkElement> wellsてその関数を呼び出しますIsElementUnderRectCursor

これは以下から着想を得ています: Kinecting the Dots

于 2012-04-27T15:10:08.360 に答える
0

Astrealはあなたの答えに再び感謝します。終わった。選択コードをmodelViewからviewに移動しました。選択はUIでのみ行われます。

private void SelectWells(RectangleGeometry selectionRectangle, FrameworkElement frameworkElement)
    {
      var items = GetItemsControl(frameworkElement);

      foreach (var item in items.Items)
      {
        var viusalItem = (ContentPresenter)items.ItemContainerGenerator.ContainerFromItem(item);

        var wellControl = this.GetWellControl(viusalItem);

        var relativePoint = wellControl.TransformToAncestor(items).Transform(new Point(0, 0));

        var controlRectangle =
          new RectangleGeometry(
            new Rect(relativePoint.X, relativePoint.Y, wellControl.ActualWidth, wellControl.ActualHeight));

        var intersectionGeometry = Geometry.Combine(
          selectionRectangle, controlRectangle, GeometryCombineMode.Intersect, null);

        if (intersectionGeometry.GetArea() > 0)
        {
          wellControl.Command.Execute(this);
        }
      }
    }
于 2012-05-07T13:14:18.410 に答える
-1

u に役立つリンク: http://www.codeproject.com/Articles/354853/WPF-Organization-Chart-Hierarchy-MVVM-Application

ユーザーがツリー内のノードをクリックしたときに、選択が変更されたことを ViewModel ノードに知らせる必要があります。イベントをコマンドとして ViewModel にルーティングしたい

于 2012-05-08T18:06:53.363 に答える