Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么单击画布上的元素总是将画布作为源发送?_C#_Wpf_Canvas_Itemscontrol - Fatal编程技术网

C# 为什么单击画布上的元素总是将画布作为源发送?

C# 为什么单击画布上的元素总是将画布作为源发送?,c#,wpf,canvas,itemscontrol,C#,Wpf,Canvas,Itemscontrol,所以我试图在我的项目中实现一个移动和调整大小的操作。我看到了一些代码并试图使其工作,但无论我尝试什么,每次单击都会注册为在画布上的单击,即使我正在单击我的ItemControl 我的XAML如下所示: <UserControl x:Class="Editor.Views.UI_Sketches.UiSketchCanvas" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="

所以我试图在我的项目中实现一个移动和调整大小的操作。我看到了一些代码并试图使其工作,但无论我尝试什么,每次单击都会注册为在
画布上的单击,即使我正在单击我的
ItemControl

我的
XAML
如下所示:

<UserControl x:Class="Editor.Views.UI_Sketches.UiSketchCanvas"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         xmlns:cc="clr-namespace:Editor.Views.CustomControls"
         xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
         mc:Ignorable="d"
    Background="{DynamicResource  BG}"
         Height="Auto" Width="Auto">

<ItemsControl Name="UItemsControl" ItemsSource="{Binding FlattenedRectanglesCollection}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <cc:CustomCanvas Background="Transparent"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemContainerStyle>
        <Style TargetType="ContentPresenter">
            <Setter Property="Canvas.Left" Value="{Binding X}"></Setter>
            <Setter Property="Canvas.Top" Value="{Binding Y}"></Setter>
        </Style>
    </ItemsControl.ItemContainerStyle>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
                <Label Content="{Binding Name}"/>
                <Rectangle Width="{Binding Width}" Height="{Binding Height}" Stroke="White" Fill="DarkGray" IsHitTestVisible="False"></Rectangle>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>
class CustomCanvas:Canvas
{
        AdornerLayer aLayer;
        bool _isDown;
        bool _isDragging;
        bool selected = false;
        UIElement selectedElement = null;
        private ContentPresenter selectedPresenter = null;

        Point _startPoint;
        private double _originalLeft;
        private double _originalTop;

        public CustomCanvas()
        {
            Loaded += CustomCanvas_OnLoaded;
        }

        private void CustomCanvas_OnLoaded(object sender, RoutedEventArgs e)
        {
            this.MouseLeftButtonDown += new MouseButtonEventHandler(CustomCanvas_MouseLeftButtonDown);
            this.MouseLeftButtonUp += new MouseButtonEventHandler(DragFinishedMouseHandler);
            this.MouseMove += new MouseEventHandler(CustomCanvas_MouseMove);
            this.MouseLeave += new MouseEventHandler(CustomCanvas_MouseLeave);

            PreviewMouseLeftButtonDown += new MouseButtonEventHandler(CustomCanvas_PreviewMouseLeftButtonDown);
            PreviewMouseLeftButtonUp += new MouseButtonEventHandler(DragFinishedMouseHandler);
        }

        // Handler for drag stopping on leaving the window
        void CustomCanvas_MouseLeave(object sender, MouseEventArgs e)
        {
            StopDragging();
            e.Handled = true;
        }

        // Handler for drag stopping on user choise
        void DragFinishedMouseHandler(object sender, MouseButtonEventArgs e)
        {
            StopDragging();
            e.Handled = true;
        }

        // Method for stopping dragging
        private void StopDragging()
        {
            if (_isDown)
            {
                _isDown = false;
                _isDragging = false;
            }
        }

        // Hanler for providing drag operation with selected element
        void CustomCanvas_MouseMove(object sender, MouseEventArgs e)
        {
            if (_isDown)
            {
                if ((_isDragging == false) &&
                    ((Math.Abs(e.GetPosition(this).X - _startPoint.X) > SystemParameters.MinimumHorizontalDragDistance) ||
                     (Math.Abs(e.GetPosition(this).Y - _startPoint.Y) > SystemParameters.MinimumVerticalDragDistance)))
                    _isDragging = true;

                if (_isDragging)
                {
                    Point position = Mouse.GetPosition(this);
                    Canvas.SetTop(selectedPresenter, position.Y - (_startPoint.Y - _originalTop));
                    Canvas.SetLeft(selectedPresenter, position.X - (_startPoint.X - _originalLeft));
                }
            }
        }

        // Handler for clearing element selection, adorner removal
        void CustomCanvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (selected)
            {
                selected = false;
                if (selectedElement != null)
                {
                    aLayer.Remove(aLayer.GetAdorners(selectedElement)[0]);
                    selectedElement = null;
                }
            }
        }

        // Handler for element selection on the canvas providing resizing adorner
        void CustomCanvas_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            selectedElement = e.Source as UIElement;
            selectedPresenter = System.Windows.Media.VisualTreeHelper.GetParent(selectedElement) as ContentPresenter;

            // Remove selection on clicking anywhere the window
            if (selected)
            {
                selected = false;
                if (selectedElement != null)
                {
                    // Remove the adorner from the selected element
                    aLayer.Remove(aLayer.GetAdorners(selectedElement)[0]);
                    selectedElement = null;
                }
            }

            // If any element except canvas is clicked, 
            // assign the selected element and add the adorner
            if (e.Source != null)
            {
                _isDown = true;
                _startPoint = e.GetPosition(this);

                selectedElement = e.Source as UIElement;

                _originalLeft = Canvas.GetLeft(selectedPresenter);
                _originalTop = Canvas.GetTop(selectedPresenter);

                aLayer = AdornerLayer.GetAdornerLayer(selectedElement);
                aLayer.Add(new ResizingAdorner(selectedElement));
                selected = true;
                e.Handled = true;
            }
        }
    }
public class ResizingAdorner : Adorner
{
    // Resizing adorner uses Thumbs for visual elements.  
    // The Thumbs have built-in mouse input handling.
    Thumb topLeft, topRight, bottomLeft, bottomRight;

    // To store and manage the adorner's visual children.
    VisualCollection visualChildren;

    // Initialize the ResizingAdorner.
    public ResizingAdorner(UIElement adornedElement)
        : base(adornedElement)
    {
        visualChildren = new VisualCollection(this);

        // Call a helper method to initialize the Thumbs
        // with a customized cursors.
        BuildAdornerCorner(ref topLeft, Cursors.SizeNWSE);
        BuildAdornerCorner(ref topRight, Cursors.SizeNESW);
        BuildAdornerCorner(ref bottomLeft, Cursors.SizeNESW);
        BuildAdornerCorner(ref bottomRight, Cursors.SizeNWSE);

        // Add handlers for resizing.
        bottomLeft.DragDelta += new DragDeltaEventHandler(HandleBottomLeft);
        bottomRight.DragDelta += new DragDeltaEventHandler(HandleBottomRight);
        topLeft.DragDelta += new DragDeltaEventHandler(HandleTopLeft);
        topRight.DragDelta += new DragDeltaEventHandler(HandleTopRight);
    }

    // Handler for resizing from the bottom-right.
    void HandleBottomRight(object sender, DragDeltaEventArgs args)
    {
        FrameworkElement adornedElement = this.AdornedElement as FrameworkElement;
        Thumb hitThumb = sender as Thumb;

        if (adornedElement == null || hitThumb == null) return;
        FrameworkElement parentElement = adornedElement.Parent as FrameworkElement;

        // Ensure that the Width and Height are properly initialized after the resize.
        EnforceSize(adornedElement);

        // Change the size by the amount the user drags the mouse, as long as it's larger 
        // than the width or height of an adorner, respectively.
        adornedElement.Width = Math.Max(adornedElement.Width + args.HorizontalChange, hitThumb.DesiredSize.Width);
        adornedElement.Height = Math.Max(args.VerticalChange + adornedElement.Height, hitThumb.DesiredSize.Height);
    }

    // Handler for resizing from the top-right.
    void HandleTopRight(object sender, DragDeltaEventArgs args)
    {
        FrameworkElement adornedElement = this.AdornedElement as FrameworkElement;
        Thumb hitThumb = sender as Thumb;

        if (adornedElement == null || hitThumb == null) return;
        FrameworkElement parentElement = adornedElement.Parent as FrameworkElement;

        // Ensure that the Width and Height are properly initialized after the resize.
        EnforceSize(adornedElement);

        // Change the size by the amount the user drags the mouse, as long as it's larger 
        // than the width or height of an adorner, respectively.
        adornedElement.Width = Math.Max(adornedElement.Width + args.HorizontalChange, hitThumb.DesiredSize.Width);
        //adornedElement.Height = Math.Max(adornedElement.Height - args.VerticalChange, hitThumb.DesiredSize.Height);

        double height_old = adornedElement.Height;
        double height_new = Math.Max(adornedElement.Height - args.VerticalChange, hitThumb.DesiredSize.Height);
        double top_old = Canvas.GetTop(adornedElement);
        adornedElement.Height = height_new;
        Canvas.SetTop(adornedElement, top_old - (height_new - height_old));
    }

    // Handler for resizing from the top-left.
    void HandleTopLeft(object sender, DragDeltaEventArgs args)
    {
        FrameworkElement adornedElement = AdornedElement as FrameworkElement;
        Thumb hitThumb = sender as Thumb;

        if (adornedElement == null || hitThumb == null) return;

        // Ensure that the Width and Height are properly initialized after the resize.
        EnforceSize(adornedElement);

        // Change the size by the amount the user drags the mouse, as long as it's larger 
        // than the width or height of an adorner, respectively.
        //adornedElement.Width = Math.Max(adornedElement.Width - args.HorizontalChange, hitThumb.DesiredSize.Width);
        //adornedElement.Height = Math.Max(adornedElement.Height - args.VerticalChange, hitThumb.DesiredSize.Height);

        double width_old = adornedElement.Width;
        double width_new = Math.Max(adornedElement.Width - args.HorizontalChange, hitThumb.DesiredSize.Width);
        double left_old = Canvas.GetLeft(adornedElement);
        adornedElement.Width = width_new;
        Canvas.SetLeft(adornedElement, left_old - (width_new - width_old));

        double height_old = adornedElement.Height;
        double height_new = Math.Max(adornedElement.Height - args.VerticalChange, hitThumb.DesiredSize.Height);
        double top_old = Canvas.GetTop(adornedElement);
        adornedElement.Height = height_new;
        Canvas.SetTop(adornedElement, top_old - (height_new - height_old));
    }

    // Handler for resizing from the bottom-left.
    void HandleBottomLeft(object sender, DragDeltaEventArgs args)
    {
        FrameworkElement adornedElement = AdornedElement as FrameworkElement;
        Thumb hitThumb = sender as Thumb;

        if (adornedElement == null || hitThumb == null) return;

        // Ensure that the Width and Height are properly initialized after the resize.
        EnforceSize(adornedElement);

        // Change the size by the amount the user drags the mouse, as long as it's larger 
        // than the width or height of an adorner, respectively.
        //adornedElement.Width = Math.Max(adornedElement.Width - args.HorizontalChange, hitThumb.DesiredSize.Width);
        adornedElement.Height = Math.Max(args.VerticalChange + adornedElement.Height, hitThumb.DesiredSize.Height);

        double width_old = adornedElement.Width;
        double width_new = Math.Max(adornedElement.Width - args.HorizontalChange, hitThumb.DesiredSize.Width);
        double left_old = Canvas.GetLeft(adornedElement);
        adornedElement.Width = width_new;
        Canvas.SetLeft(adornedElement, left_old - (width_new - width_old));
    }

    // Arrange the Adorners.
    protected override Size ArrangeOverride(Size finalSize)
    {
        // desiredWidth and desiredHeight are the width and height of the element that's being adorned.  
        // These will be used to place the ResizingAdorner at the corners of the adorned element.  
        double desiredWidth = AdornedElement.DesiredSize.Width;
        double desiredHeight = AdornedElement.DesiredSize.Height;
        // adornerWidth & adornerHeight are used for placement as well.
        double adornerWidth = this.DesiredSize.Width;
        double adornerHeight = this.DesiredSize.Height;

        topLeft.Arrange(new Rect(-adornerWidth / 2, -adornerHeight / 2, adornerWidth, adornerHeight));
        topRight.Arrange(new Rect(desiredWidth - adornerWidth / 2, -adornerHeight / 2, adornerWidth, adornerHeight));
        bottomLeft.Arrange(new Rect(-adornerWidth / 2, desiredHeight - adornerHeight / 2, adornerWidth, adornerHeight));
        bottomRight.Arrange(new Rect(desiredWidth - adornerWidth / 2, desiredHeight - adornerHeight / 2, adornerWidth, adornerHeight));

        // Return the final size.
        return finalSize;
    }

    // Helper method to instantiate the corner Thumbs, set the Cursor property, 
    // set some appearance properties, and add the elements to the visual tree.
    void BuildAdornerCorner(ref Thumb cornerThumb, Cursor customizedCursor)
    {
        if (cornerThumb != null) return;

        cornerThumb = new Thumb();

        // Set some arbitrary visual characteristics.
        cornerThumb.Cursor = customizedCursor;
        cornerThumb.Height = cornerThumb.Width = 10;
        cornerThumb.Opacity = 0.40;
        cornerThumb.Background = new SolidColorBrush(Colors.MediumBlue);

        visualChildren.Add(cornerThumb);
    }

    // This method ensures that the Widths and Heights are initialized.  Sizing to content produces
    // Width and Height values of Double.NaN.  Because this Adorner explicitly resizes, the Width and Height
    // need to be set first.  It also sets the maximum size of the adorned element.
    void EnforceSize(FrameworkElement adornedElement)
    {
        if (adornedElement.Width.Equals(Double.NaN))
            adornedElement.Width = adornedElement.DesiredSize.Width;
        if (adornedElement.Height.Equals(Double.NaN))
            adornedElement.Height = adornedElement.DesiredSize.Height;

        FrameworkElement parent = adornedElement.Parent as FrameworkElement;
        if (parent != null)
        {
            adornedElement.MaxHeight = parent.ActualHeight;
            adornedElement.MaxWidth = parent.ActualWidth;
        }
    }
    // Override the VisualChildrenCount and GetVisualChild properties to interface with 
    // the adorner's visual collection.
    protected override int VisualChildrenCount { get { return visualChildren.Count; } }
    protected override Visual GetVisualChild(int index) { return visualChildren[index]; }
}
而ResizingAdorner看起来是这样的:

<UserControl x:Class="Editor.Views.UI_Sketches.UiSketchCanvas"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         xmlns:cc="clr-namespace:Editor.Views.CustomControls"
         xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
         mc:Ignorable="d"
    Background="{DynamicResource  BG}"
         Height="Auto" Width="Auto">

<ItemsControl Name="UItemsControl" ItemsSource="{Binding FlattenedRectanglesCollection}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <cc:CustomCanvas Background="Transparent"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemContainerStyle>
        <Style TargetType="ContentPresenter">
            <Setter Property="Canvas.Left" Value="{Binding X}"></Setter>
            <Setter Property="Canvas.Top" Value="{Binding Y}"></Setter>
        </Style>
    </ItemsControl.ItemContainerStyle>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
                <Label Content="{Binding Name}"/>
                <Rectangle Width="{Binding Width}" Height="{Binding Height}" Stroke="White" Fill="DarkGray" IsHitTestVisible="False"></Rectangle>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>
class CustomCanvas:Canvas
{
        AdornerLayer aLayer;
        bool _isDown;
        bool _isDragging;
        bool selected = false;
        UIElement selectedElement = null;
        private ContentPresenter selectedPresenter = null;

        Point _startPoint;
        private double _originalLeft;
        private double _originalTop;

        public CustomCanvas()
        {
            Loaded += CustomCanvas_OnLoaded;
        }

        private void CustomCanvas_OnLoaded(object sender, RoutedEventArgs e)
        {
            this.MouseLeftButtonDown += new MouseButtonEventHandler(CustomCanvas_MouseLeftButtonDown);
            this.MouseLeftButtonUp += new MouseButtonEventHandler(DragFinishedMouseHandler);
            this.MouseMove += new MouseEventHandler(CustomCanvas_MouseMove);
            this.MouseLeave += new MouseEventHandler(CustomCanvas_MouseLeave);

            PreviewMouseLeftButtonDown += new MouseButtonEventHandler(CustomCanvas_PreviewMouseLeftButtonDown);
            PreviewMouseLeftButtonUp += new MouseButtonEventHandler(DragFinishedMouseHandler);
        }

        // Handler for drag stopping on leaving the window
        void CustomCanvas_MouseLeave(object sender, MouseEventArgs e)
        {
            StopDragging();
            e.Handled = true;
        }

        // Handler for drag stopping on user choise
        void DragFinishedMouseHandler(object sender, MouseButtonEventArgs e)
        {
            StopDragging();
            e.Handled = true;
        }

        // Method for stopping dragging
        private void StopDragging()
        {
            if (_isDown)
            {
                _isDown = false;
                _isDragging = false;
            }
        }

        // Hanler for providing drag operation with selected element
        void CustomCanvas_MouseMove(object sender, MouseEventArgs e)
        {
            if (_isDown)
            {
                if ((_isDragging == false) &&
                    ((Math.Abs(e.GetPosition(this).X - _startPoint.X) > SystemParameters.MinimumHorizontalDragDistance) ||
                     (Math.Abs(e.GetPosition(this).Y - _startPoint.Y) > SystemParameters.MinimumVerticalDragDistance)))
                    _isDragging = true;

                if (_isDragging)
                {
                    Point position = Mouse.GetPosition(this);
                    Canvas.SetTop(selectedPresenter, position.Y - (_startPoint.Y - _originalTop));
                    Canvas.SetLeft(selectedPresenter, position.X - (_startPoint.X - _originalLeft));
                }
            }
        }

        // Handler for clearing element selection, adorner removal
        void CustomCanvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (selected)
            {
                selected = false;
                if (selectedElement != null)
                {
                    aLayer.Remove(aLayer.GetAdorners(selectedElement)[0]);
                    selectedElement = null;
                }
            }
        }

        // Handler for element selection on the canvas providing resizing adorner
        void CustomCanvas_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            selectedElement = e.Source as UIElement;
            selectedPresenter = System.Windows.Media.VisualTreeHelper.GetParent(selectedElement) as ContentPresenter;

            // Remove selection on clicking anywhere the window
            if (selected)
            {
                selected = false;
                if (selectedElement != null)
                {
                    // Remove the adorner from the selected element
                    aLayer.Remove(aLayer.GetAdorners(selectedElement)[0]);
                    selectedElement = null;
                }
            }

            // If any element except canvas is clicked, 
            // assign the selected element and add the adorner
            if (e.Source != null)
            {
                _isDown = true;
                _startPoint = e.GetPosition(this);

                selectedElement = e.Source as UIElement;

                _originalLeft = Canvas.GetLeft(selectedPresenter);
                _originalTop = Canvas.GetTop(selectedPresenter);

                aLayer = AdornerLayer.GetAdornerLayer(selectedElement);
                aLayer.Add(new ResizingAdorner(selectedElement));
                selected = true;
                e.Handled = true;
            }
        }
    }
public class ResizingAdorner : Adorner
{
    // Resizing adorner uses Thumbs for visual elements.  
    // The Thumbs have built-in mouse input handling.
    Thumb topLeft, topRight, bottomLeft, bottomRight;

    // To store and manage the adorner's visual children.
    VisualCollection visualChildren;

    // Initialize the ResizingAdorner.
    public ResizingAdorner(UIElement adornedElement)
        : base(adornedElement)
    {
        visualChildren = new VisualCollection(this);

        // Call a helper method to initialize the Thumbs
        // with a customized cursors.
        BuildAdornerCorner(ref topLeft, Cursors.SizeNWSE);
        BuildAdornerCorner(ref topRight, Cursors.SizeNESW);
        BuildAdornerCorner(ref bottomLeft, Cursors.SizeNESW);
        BuildAdornerCorner(ref bottomRight, Cursors.SizeNWSE);

        // Add handlers for resizing.
        bottomLeft.DragDelta += new DragDeltaEventHandler(HandleBottomLeft);
        bottomRight.DragDelta += new DragDeltaEventHandler(HandleBottomRight);
        topLeft.DragDelta += new DragDeltaEventHandler(HandleTopLeft);
        topRight.DragDelta += new DragDeltaEventHandler(HandleTopRight);
    }

    // Handler for resizing from the bottom-right.
    void HandleBottomRight(object sender, DragDeltaEventArgs args)
    {
        FrameworkElement adornedElement = this.AdornedElement as FrameworkElement;
        Thumb hitThumb = sender as Thumb;

        if (adornedElement == null || hitThumb == null) return;
        FrameworkElement parentElement = adornedElement.Parent as FrameworkElement;

        // Ensure that the Width and Height are properly initialized after the resize.
        EnforceSize(adornedElement);

        // Change the size by the amount the user drags the mouse, as long as it's larger 
        // than the width or height of an adorner, respectively.
        adornedElement.Width = Math.Max(adornedElement.Width + args.HorizontalChange, hitThumb.DesiredSize.Width);
        adornedElement.Height = Math.Max(args.VerticalChange + adornedElement.Height, hitThumb.DesiredSize.Height);
    }

    // Handler for resizing from the top-right.
    void HandleTopRight(object sender, DragDeltaEventArgs args)
    {
        FrameworkElement adornedElement = this.AdornedElement as FrameworkElement;
        Thumb hitThumb = sender as Thumb;

        if (adornedElement == null || hitThumb == null) return;
        FrameworkElement parentElement = adornedElement.Parent as FrameworkElement;

        // Ensure that the Width and Height are properly initialized after the resize.
        EnforceSize(adornedElement);

        // Change the size by the amount the user drags the mouse, as long as it's larger 
        // than the width or height of an adorner, respectively.
        adornedElement.Width = Math.Max(adornedElement.Width + args.HorizontalChange, hitThumb.DesiredSize.Width);
        //adornedElement.Height = Math.Max(adornedElement.Height - args.VerticalChange, hitThumb.DesiredSize.Height);

        double height_old = adornedElement.Height;
        double height_new = Math.Max(adornedElement.Height - args.VerticalChange, hitThumb.DesiredSize.Height);
        double top_old = Canvas.GetTop(adornedElement);
        adornedElement.Height = height_new;
        Canvas.SetTop(adornedElement, top_old - (height_new - height_old));
    }

    // Handler for resizing from the top-left.
    void HandleTopLeft(object sender, DragDeltaEventArgs args)
    {
        FrameworkElement adornedElement = AdornedElement as FrameworkElement;
        Thumb hitThumb = sender as Thumb;

        if (adornedElement == null || hitThumb == null) return;

        // Ensure that the Width and Height are properly initialized after the resize.
        EnforceSize(adornedElement);

        // Change the size by the amount the user drags the mouse, as long as it's larger 
        // than the width or height of an adorner, respectively.
        //adornedElement.Width = Math.Max(adornedElement.Width - args.HorizontalChange, hitThumb.DesiredSize.Width);
        //adornedElement.Height = Math.Max(adornedElement.Height - args.VerticalChange, hitThumb.DesiredSize.Height);

        double width_old = adornedElement.Width;
        double width_new = Math.Max(adornedElement.Width - args.HorizontalChange, hitThumb.DesiredSize.Width);
        double left_old = Canvas.GetLeft(adornedElement);
        adornedElement.Width = width_new;
        Canvas.SetLeft(adornedElement, left_old - (width_new - width_old));

        double height_old = adornedElement.Height;
        double height_new = Math.Max(adornedElement.Height - args.VerticalChange, hitThumb.DesiredSize.Height);
        double top_old = Canvas.GetTop(adornedElement);
        adornedElement.Height = height_new;
        Canvas.SetTop(adornedElement, top_old - (height_new - height_old));
    }

    // Handler for resizing from the bottom-left.
    void HandleBottomLeft(object sender, DragDeltaEventArgs args)
    {
        FrameworkElement adornedElement = AdornedElement as FrameworkElement;
        Thumb hitThumb = sender as Thumb;

        if (adornedElement == null || hitThumb == null) return;

        // Ensure that the Width and Height are properly initialized after the resize.
        EnforceSize(adornedElement);

        // Change the size by the amount the user drags the mouse, as long as it's larger 
        // than the width or height of an adorner, respectively.
        //adornedElement.Width = Math.Max(adornedElement.Width - args.HorizontalChange, hitThumb.DesiredSize.Width);
        adornedElement.Height = Math.Max(args.VerticalChange + adornedElement.Height, hitThumb.DesiredSize.Height);

        double width_old = adornedElement.Width;
        double width_new = Math.Max(adornedElement.Width - args.HorizontalChange, hitThumb.DesiredSize.Width);
        double left_old = Canvas.GetLeft(adornedElement);
        adornedElement.Width = width_new;
        Canvas.SetLeft(adornedElement, left_old - (width_new - width_old));
    }

    // Arrange the Adorners.
    protected override Size ArrangeOverride(Size finalSize)
    {
        // desiredWidth and desiredHeight are the width and height of the element that's being adorned.  
        // These will be used to place the ResizingAdorner at the corners of the adorned element.  
        double desiredWidth = AdornedElement.DesiredSize.Width;
        double desiredHeight = AdornedElement.DesiredSize.Height;
        // adornerWidth & adornerHeight are used for placement as well.
        double adornerWidth = this.DesiredSize.Width;
        double adornerHeight = this.DesiredSize.Height;

        topLeft.Arrange(new Rect(-adornerWidth / 2, -adornerHeight / 2, adornerWidth, adornerHeight));
        topRight.Arrange(new Rect(desiredWidth - adornerWidth / 2, -adornerHeight / 2, adornerWidth, adornerHeight));
        bottomLeft.Arrange(new Rect(-adornerWidth / 2, desiredHeight - adornerHeight / 2, adornerWidth, adornerHeight));
        bottomRight.Arrange(new Rect(desiredWidth - adornerWidth / 2, desiredHeight - adornerHeight / 2, adornerWidth, adornerHeight));

        // Return the final size.
        return finalSize;
    }

    // Helper method to instantiate the corner Thumbs, set the Cursor property, 
    // set some appearance properties, and add the elements to the visual tree.
    void BuildAdornerCorner(ref Thumb cornerThumb, Cursor customizedCursor)
    {
        if (cornerThumb != null) return;

        cornerThumb = new Thumb();

        // Set some arbitrary visual characteristics.
        cornerThumb.Cursor = customizedCursor;
        cornerThumb.Height = cornerThumb.Width = 10;
        cornerThumb.Opacity = 0.40;
        cornerThumb.Background = new SolidColorBrush(Colors.MediumBlue);

        visualChildren.Add(cornerThumb);
    }

    // This method ensures that the Widths and Heights are initialized.  Sizing to content produces
    // Width and Height values of Double.NaN.  Because this Adorner explicitly resizes, the Width and Height
    // need to be set first.  It also sets the maximum size of the adorned element.
    void EnforceSize(FrameworkElement adornedElement)
    {
        if (adornedElement.Width.Equals(Double.NaN))
            adornedElement.Width = adornedElement.DesiredSize.Width;
        if (adornedElement.Height.Equals(Double.NaN))
            adornedElement.Height = adornedElement.DesiredSize.Height;

        FrameworkElement parent = adornedElement.Parent as FrameworkElement;
        if (parent != null)
        {
            adornedElement.MaxHeight = parent.ActualHeight;
            adornedElement.MaxWidth = parent.ActualWidth;
        }
    }
    // Override the VisualChildrenCount and GetVisualChild properties to interface with 
    // the adorner's visual collection.
    protected override int VisualChildrenCount { get { return visualChildren.Count; } }
    protected override Visual GetVisualChild(int index) { return visualChildren[index]; }
}
你们能告诉我为什么即使我点击元素,源代码总是
CustomCanvas


我尝试在
CustomCanvas\u PreviewMouseLeftButtonDown
中获取单击的元素(矩形),然后获取父元素(
ContentPresenter
),以便能够移动它。然而,
e.Source
始终是画布,无论我点击哪里。

我对自己的愚蠢感到惊讶,但检查代码的每一行时,我意识到
ishitestvisible=“False”
可能会导致在单击时检测矩形时出现问题。

谢谢您的代码转储-您能告诉我您指的是哪一行吗?我们在这里讨论的是哪种方法?e.OriginalSource和sender包含什么?这里的答案是:建议您可以使用鼠标。DirectlyOverproperty@o_weissman鼠标直接覆盖出于某种原因返回CustomCanvas。发送方和e.OriginalSource相同