Страница: 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 | 
 
		
			Поиск по форуму