none
Readonly Attribut einer Eigenschaft zur Laufzeit ändern RRS feed

  • Frage

  • Hi ihr,

    ich habe ein Klasse mit Eigenschaften.

    Wie kann man eine Eigenschaft aufgrund einer Wertes einer anderen Eigenschaft readonly bzw. nicht readonly setzen.

    Die Daten werden in einem Datagridview angezeigt und dort dürfen normalerweise alle Eigenschaften bearbeitet werden.

     

    Gruß George

     

    Mittwoch, 22. Juni 2011 09:32

Antworten

Alle Antworten

  • Hallo George,

    eine Eigenschaft schreibgeschützt zu behandeln ginge zur Laufzeit über einen CustomTypeDescriptor,
    siehe auch Übersicht über den Typdeskriptor, da es von der Datenbindung honoriert wird.
    Allerdings ist der Aufwand dafür relativ hoch.

    Einfacher kann es sein, dies das DataGridView selbst zu behandeln, z. B. im CellBeginEdit
    siehe: http://www.dotnetmonster.com/Uwe/Forum.aspx/winform-controls/4469/Set-readonly-property-on-cell-level-in-a-datagridview

    Gruß Elmar

    Mittwoch, 22. Juni 2011 10:11
    Beantworter
  • Hi Elmar,

    das ganze im Datagridview zu behandeln, habe ich vorerst gemacht, aber ich wollte diese Logik natürlich gerne von der Ansicht trennen, und das die jeweilige Instanz des Objekts selber übernehmen lassen, da dieses Objekt teilweise auch an andere Controls gebunden wird.

    Also werde ich mich mal mit dem CustomTypeDescriptor geschäftigen müssen.

    Danke für Deine Antwort.

    Gruß George

    Mittwoch, 22. Juni 2011 10:58
  • Hi Elmar,

     

    ich habe mich mal daran gemacht, das ganze zu versuchen, aber irgendwie komme ich da nicht weiter.

    Bei mir wird in der Liste der Objekte immer nur das erste Objekt in der Liste der Objekte abgefragt, und nicht das aktuelle.

     

    Imports System.ComponentModel
    
    Public Class Form1
        Dim meineleute As New Leute
        Dim mynew As Person
        Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
            mynew = New Person("Muster", "Frau", Person.Geschlecht.Weiblich)
            meineleute.Add(mynew)
            mynew = New Person("Muster", "Herr", Person.Geschlecht.Männlich)
            meineleute.Add(mynew)
    
            Me.DataGridView1.DataSource = meineleute.Bindingsource
        End Sub
    End Class
    Public Class Leute
        Inherits System.ComponentModel.BindingList(Of Person)
    
        Private WithEvents _Bindingsource As System.Windows.Forms.BindingSource
        Public Property Bindingsource() As System.Windows.Forms.BindingSource
            Get
                If _Bindingsource Is Nothing Then
                    _Bindingsource = New System.Windows.Forms.BindingSource
                    _Bindingsource.DataSource = Me
                End If
    
                Return _Bindingsource
            End Get
            Set(ByVal value As System.Windows.Forms.BindingSource)
                _Bindingsource = value
            End Set
        End Property
    
        Private Sub _Bindingsource_PositionChanged(sender As Object, e As System.EventArgs) Handles _Bindingsource.PositionChanged
            Debug.Print("Positionsänderung. Aktuelle Position {0}", _Bindingsource.Position.ToString)
            Debug.Print("Aktuelle Person: " & Me(_Bindingsource.Position).ToString)
            MyBase.OnListChanged(New ListChangedEventArgs(ListChangedType.PropertyDescriptorChanged, _Bindingsource.Position, CType(_Bindingsource.Item(_Bindingsource.Position), Person).GetProperties.Find("Geburtsname", True)))
        End Sub
    End Class
    
    Public Class Person
        Implements ICustomTypeDescriptor
        Implements INotifyPropertyChanged
    
        Public Sub New()
            Me.New(String.Empty, String.Empty, Geschlecht.Männlich)
        End Sub
        Public Sub New(Name As String, Vorname As String, Geschlecht As Geschlecht)
            _Vorname = Vorname
            _Nachname = Name
            _Geschlecht = Geschlecht
        End Sub
        Public Enum Geschlecht
            Männlich
            Weiblich
        End Enum
        Private _Vorname As String
        Public Property Vorname() As String
            Get
                Return _Vorname
            End Get
            Set(ByVal value As String)
                _Vorname = value
                RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("Vorname"))
            End Set
        End Property
        Private _Nachname As String
        Public Property Nachname() As String
            Get
                Return _Nachname
            End Get
            Set(ByVal value As String)
                _Nachname = value
                RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("Nachname"))
            End Set
        End Property
        Private _Geschlecht As Geschlecht
        Public Property Typ() As Geschlecht
            Get
                Return _Geschlecht
            End Get
            Set(ByVal value As Geschlecht)
                _Geschlecht = value
                RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("Typ"))
            End Set
        End Property
        Private _Geburtsname As String
        Public Property Geburtsname() As String
            Get
                Return _Geburtsname
            End Get
            Set(ByVal value As String)
                _Geburtsname = value
            End Set
        End Property
    
        Public Overrides Function ToString() As String
            Return String.Format("{0} {1}", Me.Vorname, Me.Nachname)
        End Function
    
        Public Function GetAttributes() As System.ComponentModel.AttributeCollection Implements System.ComponentModel.ICustomTypeDescriptor.GetAttributes
            Return TypeDescriptor.GetAttributes(Me, True)
        End Function
    
        Public Function GetClassName() As String Implements System.ComponentModel.ICustomTypeDescriptor.GetClassName
            Return TypeDescriptor.GetClassName(Me, True)
        End Function
    
        Public Function GetComponentName() As String Implements System.ComponentModel.ICustomTypeDescriptor.GetComponentName
            Return TypeDescriptor.GetComponentName(Me, True)
        End Function
    
        Public Function GetConverter() As System.ComponentModel.TypeConverter Implements System.ComponentModel.ICustomTypeDescriptor.GetConverter
            Return TypeDescriptor.GetConverter(Me, True)
        End Function
    
        Public Function GetDefaultEvent() As System.ComponentModel.EventDescriptor Implements System.ComponentModel.ICustomTypeDescriptor.GetDefaultEvent
            Return TypeDescriptor.GetDefaultEvent(Me, True)
        End Function
    
        Public Function GetDefaultProperty() As System.ComponentModel.PropertyDescriptor Implements System.ComponentModel.ICustomTypeDescriptor.GetDefaultProperty
            Return TypeDescriptor.GetDefaultProperty(Me, True)
        End Function
    
        Public Function GetEditor(editorBaseType As System.Type) As Object Implements System.ComponentModel.ICustomTypeDescriptor.GetEditor
            Return TypeDescriptor.GetEditor(Me, editorBaseType, True)
        End Function
    
        Public Function GetEvents() As System.ComponentModel.EventDescriptorCollection Implements System.ComponentModel.ICustomTypeDescriptor.GetEvents
            Return TypeDescriptor.GetEvents(Me, True)
        End Function
    
        Public Function GetEvents(attributes() As System.Attribute) As System.ComponentModel.EventDescriptorCollection Implements System.ComponentModel.ICustomTypeDescriptor.GetEvents
            Return TypeDescriptor.GetEvents(Me, attributes, True)
        End Function
    
        Public Function GetProperties() As System.ComponentModel.PropertyDescriptorCollection Implements System.ComponentModel.ICustomTypeDescriptor.GetProperties
            Return TypeDescriptor.GetProperties(Me, True)
        End Function
    
        Public Function GetProperties(attributes() As System.Attribute) As System.ComponentModel.PropertyDescriptorCollection Implements System.ComponentModel.ICustomTypeDescriptor.GetProperties
            Dim inPdc As PropertyDescriptorCollection = TypeDescriptor.GetProperties(Me, attributes, True)
            Dim pdcs As PropertyDescriptor() = New PropertyDescriptor(inPdc.Count - 1) {}
            For i As Integer = 0 To pdcs.Length - 1
                If Me.Typ = Geschlecht.Männlich AndAlso inPdc(i).DisplayName = "Geburtsname" Then
                    For Each attrib In inPdc(i).Attributes
                        If TypeOf (attrib) Is ReadOnlyAttribute Then
                            pdcs(i) = New ReadOnlyPropertyDescriptor(inPdc(i))
                        Else
                            pdcs(i) = inPdc(i)
                        End If
                    Next
                Else
                    pdcs(i) = inPdc(i)
                End If
            Next
            Return New PropertyDescriptorCollection(pdcs, True)
        End Function
    
        Public Function GetPropertyOwner(pd As System.ComponentModel.PropertyDescriptor) As Object Implements System.ComponentModel.ICustomTypeDescriptor.GetPropertyOwner
            Return Me
        End Function
    
        Public Event PropertyChanged(sender As Object, e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
    
    End Class
    

    Für Hilfe wäre ich sehr dankbar.

     

    Gruß George

    Montag, 24. Oktober 2011 14:42