将鼠标事件从一个PictureBox控件传递到另一个C#

时间:2018-03-19 22:52:43

标签: c# winforms

正如标题所示,我试图将鼠标事件从一个控件传递到另一个控件。我对c#还是有点新鲜,甚至不确定它是否可行。我正在创建一个基本的纸牌游戏,当我在牌组上单击鼠标时,我想要弹出一张牌并拖动它而不用抬起鼠标按钮。以下是我的主表格上的套牌代码

public partial class Form1 : Form
{
    int CardWidth = 63;
    int CardHeight = 88;

    public List<Card> cards = new List<Card>();
    public List<Card> deck = new List<Card>();

    public Form1()
    {
        InitializeComponent();
        loadCards();
    }

    private void loadCards()
    {
        for(int i = 0; i < 10; i++)
        {
            cards.Add(new Card(i*CardWidth, CardHeight * 0, CardWidth, CardHeight,this));
        }

        deck.AddRange(cards);
        updateDeck();
    }

    public void updateDeck()
    {
        Console.WriteLine($"Deck has {deck.Count} cards in it!");
        int min = new[] { 4, deck.Count}.Min();

        if(deck.Count == 1)
        {
            pbDeck.Image = Properties.Resources.CardBackDefault;
        }
        if (deck.Count > 1)
        {
            switch (min)
            {
                case 2:
                    pbDeck.Image = Properties.Resources.Deck2;
                    break;
                case 3:
                    pbDeck.Image = Properties.Resources.Deck3;
                    break;
                case 4:
                    pbDeck.Image = Properties.Resources.Deck4;
                    break;
            }
        }
        if (deck.Count <= 0)
        {
            pbDeck.Image = Properties.Resources.DeckEmpty;
        }
    }

    private void pbDeck_MouseDown(object sender, MouseEventArgs e)
    {
        //Pickup Top card if exists
        if (deck.Count > 0)
        {
            //Get last value in Deck List (a.k.a. Last card placed in Deck
            Card card = deck.Last();

            //Set the card's location to the deck's location
            card.Location = pbDeck.Location;

            //Load the Card
            card.loadCard();

            //Remove the card from the deck
            deck.Remove(card);

            //Update the deck image
            updateDeck();

            card.card_MouseDown(sender, e);

            return;
        }
    }
}

这是卡类

//TODO: May need to be revisited how this value is accessed and modified
public Point Location { get; set; }

//Our Card's visual canvas
public PictureBox card;

//Reference to our main Form
private Form1 Form;

//How we know if the card has been picked up
public bool isMoving = false;

public Card(int X, int Y, int w, int h, Form1 form)
    {
        Location = new Point(X, Y);

        Form = form;

        card = new PictureBox();
        card.Image = Properties.Resources.CardDefaultTemplate;
        card.Location = Location;
        card.Name = "card";
        card.Size = new Size(w, h);
        card.SizeMode = PictureBoxSizeMode.StretchImage;
        card.TabIndex = 0;
        card.TabStop = false;
        card.MouseDown += new MouseEventHandler(card_MouseDown);
        card.MouseMove += new MouseEventHandler(card_MouseMove);
        card.MouseUp += new MouseEventHandler(card_MouseUp);
        card.Paint += new PaintEventHandler(card_Paint);
    }
    public void loadCard()
    {
        //Set the location of the card just in case it's changed
        card.Location = Location;

        //Add this object to the Form
        Form.Controls.Add(card);

        //Bring it in front of all other items on the form
        card.BringToFront();
    }

    public void removeCard()
    {
        //Remove card from form
        Form.Controls.Remove(card);
    }

    public void card_MouseDown(object sender, MouseEventArgs e)
    {
        //Let everyone know we're moving
        isMoving = true;

        //Bring card to frint of screen for visibility
        card.BringToFront();
    }

    public void card_MouseMove(object sender, MouseEventArgs e)
    {
        //If we're moving (a.k.a. Mouse is is down on the card)
        if (isMoving)
        {
            //Move the card center to mouse location
            card.Location = Form.PointToClient(new Point(Cursor.Position.X - (card.Width / 2), Cursor.Position.Y - (card.Height / 2)));
        }
    }

    private void card_MouseUp(object sender, MouseEventArgs e)
    {
        //Save the initial locations of the card
        int setX = card.Location.X;
        int setY = card.Location.Y;

        //Let everyone know we're not moving anymore
        isMoving = false;

        //If the card is past the right boundry
        if(setX+card.Width > Form.Width)
        {
            //Move it back within boundry
            setX = Form.Width - card.Width;
        }
        //If the card is past the left boundry
        else if (setX < 0)
        {
            //Move it back within boundry
            setX = 0;
        }
        //If the card is past the lower boundry
        if (setY+card.Height > Form.Height)
        {
            //Move it back within boundry
            setY = Form.Height-card.Height;
        }
        //If the card is past the upper boundry
        else if (setY < 0)
        {
            //Move it back within boundry
            setY = 0;
        }

        //Set final location
        card.Location = new Point(setX, setY);

        //If the final location is over the deck image on the form
        if (overDeck())
        {
            //Add this card to the deck
            Form.deck.Add(this);
            //Update the deck image
            Form.updateDeck();
            //Remove the card from the form
            removeCard();
        }

    }

    private bool overDeck()
    {
        //If the card's center X value is within the left and right boundries of the deck image on the form
        if (card.Location.X + (card.Width / 2) > Form.pbDeck.Location.X && card.Location.X + (card.Width / 2) < Form.pbDeck.Location.X + Form.pbDeck.Width)
        {
            //If the cards center Y value is within the left and right boundries of the deck image on the form
            if (card.Location.Y + (card.Height / 2) > Form.pbDeck.Location.Y && card.Location.Y + (card.Height / 2) < Form.pbDeck.Location.Y + Form.pbDeck.Height)
            {
                return true;
            }
        }

        //If the above is not true
        return false;
    }

当我从甲板上弹出时,卡片按照我的意图拖动,但不是当我从甲板上弹出它们时。目前,如果我取下鼠标按钮,它们将跟随光标,再次点击时会掉光,这不是理想的结果

编辑:为了清晰起见,添加了更多代码。将标题更改为更具体的标题 编辑2:从卡类中添加了缺失的变量

1 个答案:

答案 0 :(得分:0)

我不打算弄清楚你应该如何将它合并到你的代码中,但是你想要将鼠标输入转移到另一个控件的属性是Control.Capture Property

这是布尔值,您可以为要响应移动鼠标的 PictureBox设置为true。您可以在另一个控件的MouseDown事件处理程序中设置它。

为了演示,创建一个新的WinForm项目并向表单添加Label和PictureBox控件。连接以下事件处理程序并运行该程序。单击标签并拖动鼠标。 PictureBox将跟随光标。

    private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
    {
        pictureBox1.Location = this.PointToClient(pictureBox1.PointToScreen(e.Location));
    }

    private void label1_MouseDown(object sender, MouseEventArgs e)
    {
        pictureBox1.Capture = true;
    }