Атрибут RefreshProperties на уровне класса в .net, winforms + неправильно обновляет сетку свойств - PullRequest
0 голосов
/ 16 февраля 2010

У меня была странная проблема с редактированием класса в сетке свойств, из-за чего сетка свойств некорректно обновлялась.

Мне удалось свести проблему к классу с двумя свойствами.Я включил код в конце, чтобы облегчить объяснение.

Он сводится к классу с двумя свойствами.Первый из которых является расширяемым (шрифт).Сам класс является расширяемым, а также реализует метод CreateInstance в преобразователе типов.

Чтобы увидеть проблему, разверните шрифт, отредактируйте, скажем, «Полужирный», и уберите вкладку.Происходят две проблемы:

(1) Второе свойство подскакивает и заканчивается в расширенном свойстве шрифта.

(2) Знак «-» расширенного шрифта меняется на «+».

Проблема устраняется путем присоединения ResfreshProperties (RefreshProperties.All) к классу.

Это здорово, но я бы хотел понять, как это решило проблему.Я взглянул на рефлектор и не могу найти примеры присоединения RefreshProperties на уровне класса.

/// Простой класс

<TypeConverter(GetType(Class1Converter)), _
RefreshProperties(RefreshProperties.All)> _
Public Class Class1

Public Sub New(ByVal font As Font, ByVal image As Image)
    Me.New()
    Me.Image = image
    Me.Font = font
End Sub

Public Sub New()
End Sub

Private _Font As Font = New Font("Arial", 10)
Public Property Font() As Font
    Get
        Return _Font
    End Get
    Set(ByVal value As Font)
        _Font = value
    End Set
End Property

Private _Image As Image
Public Property Image() As Image
    Get
        Return _Image
    End Get
    Set(ByVal value As Image)
        _Image = value
    End Set
End Property

End Class

/// Конвертер дляclass

Public Class Class1Converter
Inherits ExpandableObjectConverter

Public Overrides Function GetCreateInstanceSupported(ByVal context As System.ComponentModel.ITypeDescriptorContext) As Boolean
    Return True
End Function

Public Overrides Function CreateInstance(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal propertyValues As System.Collections.IDictionary) As Object
    Dim font As Font = TryCast(propertyValues("Font"), Font)
    Dim image As Image = CType(propertyValues("Image"), Image)
    Return New Class1(font, image)
End Function

End Class

/// Кнопка для размещения класса

Public Class MyButton
Inherits Button

Private _C As Class1 = New Class1
Public Property C() As Class1
    Get
        Return _C
    End Get
    Set(ByVal value As Class1)
        _C = value
    End Set
End Property

End Class

1 Ответ

0 голосов
/ 16 февраля 2010

Звучит так, как будто происходит ошибка рисования в элементе управления сеткой свойств. Был ли атрибут RefreshPropertiesAttribute применен на уровне свойств при возникновении ошибки? Компонент реализует INotifyPropertyChanged?

Одна из причин того, что проблема, вероятно, исчезнет, ​​заключается в том, что применение RefreshPropertiesAttribute на уровне класса не является способом, которым атрибут должен использоваться. Я предполагаю, что, применяя его на уровне класса, вы фактически удаляете его. Похоже, что они оставили его установленным как AttributeTargets. Все, но ясно, что это не дизайн.

RefreshProperties является своего рода атрибутом отрыва. Он сообщает конструктору, что когда значение этого свойства изменяется (через сетку свойств), выполните повторный запрос всех остальных свойств этого класса. Очевидно, что это расточительно, особенно если измененное свойство не влияет на другие свойства.

Если у вас есть свойства, которые вызывают изменения в других свойствах, вы можете использовать PropName Измененный шаблон событий. В этом случае вы вызовете событие FontChanged или ImageChanged для класса, когда эти свойства изменятся. Дизайнер Windows Forms ищет события с этим соглашением об именах и использует их для аннулирования сетки свойств.

Но в приведенном вами примере эти два свойства не будут аннулировать друг друга, и поэтому вам не нужно аннулировать одно из них в ответ на другое.

...