Страница: 1 | 2 | 3 |
|
Вопрос: System.Drawing2D.GraphicsState
|
Добавлено: 29.12.08 16:07
|
|
Автор вопроса: diplay
|
У меня есть самодельная прога для рисования. Написана на VB.NET. Я хочу сделать в проге возможность отмены последних нескольких действий. Для этого использую объект типа System.Drawing2D.GraphicsState , чтобы сохранять состояние графического объекта, который рисует на самодельном элементе управления. Вот коды, связанные с этим.
Public Class Form1
Dim actions As GraphicsState() = New GraphicsState(5) {} ' состояния графики на drpPic
' тут остальной код проги
Private Sub NextAction()
actions(0) = actions(1)
actions(1) = actions(2)
actions(2) = actions(3)
actions(3) = actions(4)
actions(4) = actions(5)
actions(5) = drpPic.AState ' сохранение текущего состояния drpPic
End Sub
Private Sub ОтменитьToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ОтменитьToolStripMenuItem.Click
drpPic.Undo(actions(5)) ' восстановление состояния из массива
actions(5) = actions(4)
actions(4) = actions(3)
actions(3) = actions(2)
actions(2) = actions(1)
actions(1) = actions(0)
End Sub
End Class
Теперь код drpPic
Public Class DrawingPlace
Dim a As Graphics
Public Sub InitGraphics()
a = Me.CreateGraphics
End Sub
' тут остальной код элемента управления
Public ReadOnly Property AState() As Drawing2D.GraphicsState ' возвращает состояние графики
Get
Return a.Save
End Get
End Property
Public Sub Undo(ByVal state As GraphicsState) ' восстанавливает состояние графики
Try
a.Restore(state)
Catch
End Try
End Sub
End Class
Ответить
|
Номер ответа: 3 Автор ответа: EROS
Вопросов: 58 Ответов: 4255
|
Профиль | | #3
|
Добавлено: 29.12.08 21:56
|
Это было во первых..
Во вторых, предположим что ты все таки от чего то унаследовался.. скажем от Control. В этом случае вызов Me.CreateGraphics в конструкторе класса, маягко говоря, не совсем корректный, и вот почему:
1. В этот момент объекта, как такового, еще не существует, он только создается и еще не инициализировался! Поэтому разумно предположить что объект Graphics будет "пустой" заготовкой. Правильные программеры разделяют подобные вещи на непосредственно сам конструктор и на метод Initialize.
2. Объект Graphics величина не постоянная. Это говорит о том, что при первом же событии OnResize реальный контекст изменится а твой Graphics останется неизменным,что говорит о том, что ты работаешь с копией реального объекта.
Из всего написанного выше ты должен сделать следующие выводы:
- Объект Graphics надо пересоздавать либо по OnResize либо в OnRegionChanged либо получать ссылку в OnPaint
- Правильней всего было бы отказаться от этой безумной затеи(промежуточного хранения Graphics) и использовать Graphics который передается в методе OnPaint
Ответить
|
Номер ответа: 5 Автор ответа: diplay
Вопросов: 4 Ответов: 69
|
Профиль | | #5
|
Добавлено: 30.12.08 15:50
|
Блин, даже как-то стыдно стало( Я, школьник-самоучка, прихожу на форум к умным людям и, получив умный ответ, не могу въехать в то, что там написано.
Пытаюсь понять.......... прошло 5 минут.
Вроде чё-то понял, щас буду писать. (Если что-то понял неправильно то сильно не ругайте)
Во-первых
Я не знаю, от кого по умолчанию наследуют пользовательские элементы управления в VB.NET. Я просто нажал Проект -> Добавить пользовательский элемент управления. А потом просто стал работать с ним, как с формой. Во всяком случае, он обладает теми же свойствами и методами, что и обычная Windows-форма. Потом он у меня появился в ToolBox'e и я его добавил на форму.
Во-вторых
Метод InitGraphics() не имеет ничего общего с конструктором класса. Он вызывается из формы уже после того, как объект был создан.
Вот:
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
drpPic.InitGraphics()
End Sub
Еще не совсем понял, зачем заново вызывать CreateGraphics() по OnPaint, ведь когда я рисую, я обращаюсь к объекту a, который уже был приравнен к Me.CreateGraphics().
В-третьих
Я не разбираюсь в C#. Попытался все-таки понять. Тока что-такое GraphicPath?
Заключение
Может я немного не так выразился, но в моей проге все работает, просто не пашет отмена действий и все, а так все отлично.
Ответить
|
Номер ответа: 6 Автор ответа: EROS
Вопросов: 58 Ответов: 4255
|
Профиль | | #6
|
Добавлено: 30.12.08 17:34
|
Я не знаю, от кого по умолчанию наследуют пользовательские элементы управления в VB.NET
От класса UserControl
Метод InitGraphics() не имеет ничего общего с конструктором класса
сорри, проглядел и ошибочно принял за конструктор
Еще не совсем понял, зачем заново вызывать CreateGraphics() по OnPaint
Как раз таки наоборот.. вызывать ничего не надо! А надо использовать объект Graphics который передается в событие OnPaint в качестве аргумента (как у меня в строке e.Graphics.DrawPath(Pens.Red, user_path); )
я обращаюсь к объекту a, который уже был приравнен к Me.CreateGraphics()
Да.. так и есть.. но ты должен понимать что это не совсем полноценная ссылка. К примеру ты вызвал CreateGraphics, после этого увеличил размер контрола, и попытайся что нибудь нарисовать на новой(увеличинной) части контрола. Эта часть для тебя будет недоступна, пока ты заново не вызовешь CreateGraphics.
Тока что-такое GraphicPath?
http://msdn.microsoft.com/ru-ru/library/system.drawing.drawing2d.graphicspath.aspx
просто не пашет отмена действий и все, а так все отлично.
А ты чего ожидал? Что твой рисунок вернется к первоначальному состоянию? Старик, ты заблуждаешься.. ты, по всей видимости, не до конца осознаешь предназначение методов Save/Restore. Если верить документации(а мы ей верим, ведь так?) то эти методы сохраняют/ввостанавливают "state of this Graphics object". Т.е. это относится именно к состоянию объекта (если хочешь называй это настройками: способ интерполяции,настройки матрицы преобразования и еще куча других фишек) и никакого отношения к изображению не имеет!
Ответить
|
Страница: 1 | 2 | 3 |
Поиск по форуму