Nota
O acceso a esta páxina require autorización. Pode tentar iniciar sesión ou modificar os directorios.
O acceso a esta páxina require autorización. Pode tentar modificar os directorios.
La accesibilidad de las propiedades de dependencia de lectura y escritura a través del sistema de propiedades de Windows Presentation Foundation (WPF) hace que sean propiedades públicas. Como resultado, no es posible ofrecer garantías de seguridad sobre los valores de propiedades de dependencia de lectura-escritura. El sistema de propiedades de WPF ofrece una mayor seguridad para las propiedades dependientes de solo lectura, permitiendo restringir el acceso de escritura.
Acceso y seguridad de las envolturas de propiedad
Normalmente, un envoltorio de propiedades de Common Language Runtime (CLR) se incluye en las implementaciones de propiedades de dependencia de lectura y escritura para simplificar el acceso o la modificación de los valores de la propiedad. Si se incluye, el contenedor de propiedades CLR es un método conveniente que implementa las llamadas estáticas GetValue y SetValue, que interactúan con la propiedad de dependencia subyacente. Básicamente, un contenedor de propiedades CLR expone una propiedad de dependencia como una propiedad CLR respaldada por una propiedad de dependencia en lugar de un campo privado.
Aplicar mecanismos de seguridad y restringir el acceso al contenedor de propiedades CLR podría impedir el uso del método de conveniencia, pero esas técnicas no impedirán llamadas directas a GetValue o SetValue. En otras palabras, siempre se puede acceder a una propiedad de dependencia de lectura y escritura a través del sistema de propiedades de WPF. Si estás implementando una propiedad de dependencia de lectura/escritura, evita restringir el acceso al contenedor de propiedades CLR. En su lugar, declare el contenedor de propiedades CLR como miembro público para que los autores de llamadas conozcan el verdadero nivel de acceso de la propiedad de dependencia.
Exposición del sistema de propiedades de las propiedades de dependencia
El sistema de propiedades de WPF proporciona acceso a una propiedad de dependencia de lectura/escritura a través de su DependencyProperty identificador. El identificador se puede usar en GetValue y SetValue llamadas. Incluso si el campo de identificador estático no es público, varios aspectos del sistema de propiedades devolverán un `DependencyProperty` tal como existe en una instancia de una clase o clase heredada. Por ejemplo, el GetLocalValueEnumerator método devuelve identificadores para instancias de propiedad de dependencia con un valor establecido localmente. Además, puede sobrescribir el OnPropertyChanged método virtual para recibir datos de eventos que notificarán el identificador de las propiedades de dependencia cuyo valor ha cambiado. Para que los llamantes conozcan el nivel de acceso verdadero de una propiedad dependiente de lectura/escritura, declare el campo de su identificador como miembro público.
Nota:
Aunque declarar un campo de identificador de propiedad de dependencia como private reduce el número de formas en que se puede acceder a una propiedad de dependencia de lectura y escritura, la propiedad no será privada según la definición del lenguaje CLR.
Seguridad de validación
Aplicar un Demand a un ValidateValueCallback y esperar que la validación falle debido a un fallo en Demand no es un mecanismo de seguridad adecuado para restringir los cambios en los valores de propiedad. Además, los llamantes malintencionados pueden suprimir la invalidación del nuevo valor a través de ValidateValueCallback, si operan dentro del dominio de la aplicación.
Acceso a las propiedades de dependencia de solo lectura
Para restringir el acceso, registre su propiedad como una propiedad de dependencia de solo lectura llamando al método RegisterReadOnly. El RegisterReadOnly método devuelve un DependencyPropertyKeyobjeto , que se puede asignar a un campo de clase no público. En el caso de las propiedades de dependencia de solo lectura, el sistema de propiedades de WPF solo proporcionará acceso de escritura a aquellos que tengan una referencia a .DependencyPropertyKey Para ilustrar este comportamiento, el código de prueba siguiente:
- Crea una instancia de una clase que implementa las propiedades de dependencia de solo lectura y escritura.
- Asigna un
privatemodificador de acceso a cada identificador. - Solo implementa descriptores de
getacceso. - Usa el GetLocalValueEnumerator método para acceder a las propiedades de dependencia subyacentes a través del sistema de propiedades de WPF.
- Llama GetValue y SetValue para probar el acceso a cada valor de propiedad de dependencia.
/// <summary>
/// Test get/set access to dependency properties exposed through the WPF property system.
/// </summary>
public static void DependencyPropertyAccessTests()
{
// Instantiate a class that implements read-write and read-only dependency properties.
Aquarium _aquarium = new();
// Access each dependency property using the LocalValueEnumerator method.
LocalValueEnumerator localValueEnumerator = _aquarium.GetLocalValueEnumerator();
while (localValueEnumerator.MoveNext())
{
DependencyProperty dp = localValueEnumerator.Current.Property;
string dpType = dp.ReadOnly ? "read-only" : "read-write";
// Test read access.
Debug.WriteLine($"Attempting to get a {dpType} dependency property value...");
Debug.WriteLine($"Value ({dpType}): {(int)_aquarium.GetValue(dp)}");
// Test write access.
try
{
Debug.WriteLine($"Attempting to set a {dpType} dependency property value to 2...");
_aquarium.SetValue(dp, 2);
}
catch (InvalidOperationException e)
{
Debug.WriteLine(e.Message);
}
finally
{
Debug.WriteLine($"Value ({dpType}): {(int)_aquarium.GetValue(dp)}");
}
}
// Test output:
// Attempting to get a read-write dependency property value...
// Value (read-write): 1
// Attempting to set a read-write dependency property value to 2...
// Value (read-write): 2
// Attempting to get a read-only dependency property value...
// Value (read-only): 1
// Attempting to set a read-only dependency property value to 2...
// 'FishCountReadOnly' property was registered as read-only
// and cannot be modified without an authorization key.
// Value (read-only): 1
}
}
public class Aquarium : DependencyObject
{
public Aquarium()
{
// Assign locally-set values.
SetValue(FishCountProperty, 1);
SetValue(FishCountReadOnlyPropertyKey, 1);
}
// Failed attempt to restrict write-access by assigning the
// DependencyProperty identifier to a non-public field.
private static readonly DependencyProperty FishCountProperty =
DependencyProperty.Register(
name: "FishCount",
propertyType: typeof(int),
ownerType: typeof(Aquarium),
typeMetadata: new PropertyMetadata());
// Successful attempt to restrict write-access by assigning the
// DependencyPropertyKey to a non-public field.
private static readonly DependencyPropertyKey FishCountReadOnlyPropertyKey =
DependencyProperty.RegisterReadOnly(
name: "FishCountReadOnly",
propertyType: typeof(int),
ownerType: typeof(Aquarium),
typeMetadata: new PropertyMetadata());
// Declare public get accessors.
public int FishCount => (int)GetValue(FishCountProperty);
public int FishCountReadOnly => (int)GetValue(FishCountReadOnlyPropertyKey.DependencyProperty);
}
''' <summary>
''' ' Test get/set access to dependency properties exposed through the WPF property system.
''' </summary>
Public Shared Sub DependencyPropertyAccessTests()
' Instantiate a class that implements read-write and read-only dependency properties.
Dim _aquarium As New Aquarium()
' Access each dependency property using the LocalValueEnumerator method.
Dim localValueEnumerator As LocalValueEnumerator = _aquarium.GetLocalValueEnumerator()
While localValueEnumerator.MoveNext()
Dim dp As DependencyProperty = localValueEnumerator.Current.[Property]
Dim dpType As String = If(dp.[ReadOnly], "read-only", "read-write")
' Test read access.
Debug.WriteLine($"Attempting to get a {dpType} dependency property value...")
Debug.WriteLine($"Value ({dpType}): {CInt(_aquarium.GetValue(dp))}")
' Test write access.
Try
Debug.WriteLine($"Attempting to set a {dpType} dependency property value to 2...")
_aquarium.SetValue(dp, 2)
Catch e As InvalidOperationException
Debug.WriteLine(e.Message)
Finally
Debug.WriteLine($"Value ({dpType}): {CInt(_aquarium.GetValue(dp))}")
End Try
End While
' Test output
' Attempting to get a read-write dependency property value...
' Value (read-write): 1
' Attempting to set a read-write dependency property value to 2...
' Value (read-write): 2
' Attempting to get a read-only dependency property value...
' Value (read-only): 1
' Attempting to set a read-only dependency property value to 2...
' 'FishCountReadOnly' property was registered as read-only
' and cannot be modified without an authorization key.
' Value (read-only): 1
End Sub
End Class
Public Class Aquarium
Inherits DependencyObject
Public Sub New()
' Assign locally-set values.
SetValue(FishCountProperty, 1)
SetValue(FishCountReadOnlyPropertyKey, 1)
End Sub
' Failed attempt to restrict write-access by assigning the
' DependencyProperty identifier to a non-public field.
Private Shared ReadOnly FishCountProperty As DependencyProperty =
DependencyProperty.Register(
name:="FishCount",
propertyType:=GetType(Integer),
ownerType:=GetType(Aquarium),
typeMetadata:=New PropertyMetadata())
' Successful attempt to restrict write-access by assigning the
' DependencyPropertyKey to a non-public field.
Private Shared ReadOnly FishCountReadOnlyPropertyKey As DependencyPropertyKey =
DependencyProperty.RegisterReadOnly(
name:="FishCountReadOnly",
propertyType:=GetType(Integer),
ownerType:=GetType(Aquarium),
typeMetadata:=New PropertyMetadata())
' Declare public get accessors.
Public ReadOnly Property FishCount As Integer
Get
Return GetValue(FishCountProperty)
End Get
End Property
Public ReadOnly Property FishCountReadOnly As Integer
Get
Return GetValue(FishCountReadOnlyPropertyKey.DependencyProperty)
End Get
End Property
End Class
Consulte también
.NET Desktop feedback