Я делаю простую игру в форме winform (крестики-нолики), и у меня проблемы с рисованием управления блоком.

Вот созданный мной класс, представляющий блок в игре (без игровой логики - это только UI).

public class UI_Block : Control
{
    private Rectangle block;
    private SIGNS sign;
    public  SIGNS Sign 
    {
        get {return sign;}
        set
        {
            if (sign == SIGNS.EMPTY)
                sign = value;
        } 
    }

    public UI_Block( ) {
        sign = SIGNS.EMPTY;
    }

    public void SetBlockOnBoard(int x, int y)
    {
        this.Location = new Point( x , y );
        this.Size = new Size(Parent.Width /3, Parent.Height / 3);

        block = new Rectangle(this.Location, this.Size);
    }

    public void DrawSign(Graphics g)
    {
        Pen myPen = new Pen(Color.Red);

        if (sign == SIGNS.O)
        {
            drawO(g,new Pen(Brushes.Black));
        }

        if (sign == SIGNS.X)
        {
            drawX(g, new Pen(Brushes.Red));
        }

    }

    protected override void OnPaint(PaintEventArgs e)
    {
        DrawSign(e.Graphics);
        base.OnPaint(e);
    }

    //Draw X
    private void drawX(Graphics g, Pen myPen)
    {
        //draw first daignol
        Point daignolStart = new Point {  X = this.Location.X  ,  Y = this.Location.Y   };
        Point daignolEnd = new Point   {  X = this.Size.Width  ,  Y = this.Size.Height  };

        g.DrawLine(myPen, daignolStart, daignolEnd);

        //draw second daignol
        daignolStart = new Point {  X = Size.Width ,  Y = this.Location.Y  };
        daignolEnd = new Point   {  X = Location.X,   Y = Size.Height      };

        g.DrawLine(myPen, daignolEnd, daignolStart);
    }


    //Draw O
    private void drawO(Graphics g, Pen myPen)
    {
        g.DrawEllipse(myPen, block);
    }

}

Я добавил их оба в класс winForm и посмотреть, как они выглядят, когда я их раскрашиваю:

public partial class Form1 : Form
{
    UI.UI_Block block;
    UI.UI_Block blockX;

    public Form1()
    {
        InitializeComponent();

        block = new UI.UI_Block();
        blockX = new UI.UI_Block();
        Controls.Add(block);
        Controls.Add(blockX);

    }

    protected override void OnLoad(EventArgs e)
    {
        block. SetBlockOnBoard(0, 0);
        blockX.SetBlockOnBoard(0, block.Height);

        block.Sign = SIGNS.X;
        blockX.Sign = SIGNS.O;

        base.OnLoad(e);
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        //block.DrawSign(e.Graphics);
        //block.DrawSign(e.Graphics);
        base.OnPaint(e);
    }

}

Я пробовал несколько вещей, например, не использовал событие onPaint, но все равно получил тот же результат.

Вот что я вижу, когда запускаю его:

введите описание изображения здесь Есть идеи, почему я не могу нарисовать их обоих?

1
samy 30 Мар 2013 в 16:34
Где вы вызываете методы рисования? Все, что я вижу, это то, что вы кладете блок. Лучше всего поместить это в set для свойства Sign.
 – 
krillgar
30 Мар 2013 в 16:56
Я добавил оба блока в элементы управления winForm, поэтому методы OnPaints будут вызываться каждый раз, когда я перекрашиваю форму (form.Invalidate). я должен делать это по-другому?
 – 
samy
30 Мар 2013 в 17:05
Просмотрите свой код и посмотрите, вызывает ли он OnPaint при добавлении второго элемента управления. Возможно, вам придется добавить Graphics из формы в качестве параметра в конструктор UI_Block. По этой причине я мало работал с Paint. Не могли бы вы вместо этого просто установить значки или вам нужно использовать Paint?
 – 
krillgar
30 Мар 2013 в 17:08
Я добавил MassageBox (this.Sign + "") в OnPaint, и они оба вызываются как я thogut. Я попытался использовать объект Graphic из формы на обоих объектах (и отключил OnPaint), но увидел тот же результат. что вы имели в виду под иконками, вы имели в виду изображения?
 – 
samy
30 Мар 2013 в 17:14
Да. Добавьте изображения в ресурсы проекта, и когда вы установите Sign, используйте это, чтобы установить изображение, которое будет отображаться в UI_Block.
 – 
krillgar
30 Мар 2013 в 17:20

1 ответ

Лучший ответ

Вы не рисуете содержимое своего элемента управления в видимой области, поэтому он отображается нормально, но вы его не видите.

Каждый элемент управления имеет собственное пространство координат (клиентские координаты), которое начинается с 0,0 независимо от того, где он расположен в родительском элементе управления. Вы правильно размещаете элемент управления в его родительском элементе, устанавливая его Location, но затем вы также используете Location для смещения графики, поэтому они по существу смещаются в два раза.

(Если вы увеличите свой контроль, вы сможете увидеть, как X отображается ниже по экрану)

Чтобы исправить это, делайте весь свой рисунок в клиентском координатном пространстве вашего элемента управления, то есть рисуйте в области (0, 0, ширина, высота)

(P.S. Вы можете просто нарисовать все 9 плиток в родительском элементе управления, что является более эффективным подходом, чем создание 9 дочерних элементов управления. Но то, что вы делаете, будет работать нормально)

2
Jason Williams 30 Мар 2013 в 19:01