Pregunta

Necesito saber cuál es el procedimiento para hacer una escritura de dependencia de sólo-propiedad. Puedo ver que la clase DependencyProperty no tiene un método especial "Registro" para las propiedades de sólo escritura, pero no tengo ni idea de si el método RegisterAttached puede aplicarse a lo que estoy tratando de hacer.

Esta propiedad tiene que ser una dependencia de la propiedad, en lugar de una simple propiedad CLR. Internamente, mi clase requiere un PropertyChangedCallback en esta propiedad con el fin de permanecer estable.

Yo sé que la dependencia-propiedades de sólo escritura se pueden crear, ya que se define claramente en:
Pro C # 2008 y la Plataforma 1 # v = OnePage .NET 3.5 , Página 1061 .
Sin embargo, este es el único lugar donde puedo incluso encontrar "propiedad de dependencia" y "sólo escritura" en la misma página. Y este autor aparentemente no creía que fuera necesario para realmente mostrar al lector el procedimiento para otra cosa que no sea una lectura-escritura de dependencia de propiedad básica. Por supuesto, este libro podría ser una carga de BS - pero este libro se ve bastante estándar, por lo que creo que es una apuesta bastante segura de que el autor es correcta. Asumo la falta de información en Internet se deriva del hecho de que nadie necesita generalmente para hacer una propiedad como esta.

Sé que suena muy cuestionable a querer hacer su propia escritura de dependencia de sólo-propiedad. Te aseguro que tiene sentido en que lo quiero. Mi clase tiene una propiedad cuyo valor sólo es útil al objeto de ajustarlo. Si fuera otro objeto de solicitar el valor de esta propiedad después, no sería capaz de hacer cualquier sentido racional del valor sin conocer el contexto original de la incubadora.

Esta propiedad no está destinado a ser utilizado con fines informativos. Dejar objetos fuera intentan utilizar el valor de la propiedad de esta manera es problemático, peligroso y un riesgo de seguridad. Así que creo que el mejor diseño es prohibir las operaciones de lectura en esta propiedad. Cualquier persona que use mi clase se encontrará con que se ven obligados a utilizar la clase de la manera que se esperaba, que funcionará mucho mejor y más limpio en el final.

¿Fue útil?

Solución

No se puede, esto parece ser por diseño. Aunque puedo entender su acercamiento al libro mencionado y estoy de ninguna manera cuestionar su calidad, yo todavía presumo de ser una especie de copiar y pegar o problema similar esto. Aquí está mi razonamiento:

WPF código de sistema de propiedad

diseño del sistema de propiedades de WPF

  • Más importante, 'La actual aplicación de WPF XAML de su procesador es inherentemente propiedad de dependencia de conciencia. El procesador WPF XAML utiliza métodos sistema de propiedad para las propiedades de dependencia cuando se carga XAML y procesamiento atributos binarios que son propiedades de dependencia. Esto evita eficazmente las envolturas de propiedad. ", ver Cargando XAML y Dependencia propiedades .
  • Lo más importante, 'Las propiedades de dependencia debería ser generalmente considerados como bienes de dominio público. La naturaleza de la (WPF) sistema de propiedad de Windows Presentation Foundation impide la capacidad de hacer las garantías de seguridad alrededor de un valor de propiedad de dependencia. ", ver propiedades de dependencia de Seguridad .

Especialmente los dos últimos puntos están perfilando la restricción de diseño, que los valores de propiedad de dependencia siempre son accesibles a través de GetValue () / EstablecerValor () , no importa si sus envolturas CLR se restringen el acceso o disponibles en absoluto, con la única excepción de la representó específicamente para Read-Only propiedades de dependencia .

En consecuencia, como Jeffs respuesta implica ya, sólo la eliminación del captador, por ejemplo, en realidad no se evitar que cualquier persona el acceso a la propiedad a través de GetValue () , aunque esto puede al menos 'reducir el espacio de nombres inmediatamente expuesta de una clase personalizada' . La utilidad de dicha solución semántica de hacer el propevalor rty algo menos visible / accesibles y el valor recuperado inherentemente inútil para los clientes como se sugiere por Jeff depende de su situación particular, por supuesto.

Otros consejos

Interesante, esto es sin duda un escenario poco frecuente, estaría interesado en escuchar más de lo que permite.

¿Usted consideraría la idea de proporcionar un valor no válido (como nulo) para lee a través de la unión o GetValue, mientras que sólo el no tener un captador CLR?

Utilice un DependencyProperty privada para almacenar el valor "real" que te importa, o sólo una variable miembro privada.

En la propiedad de devolución de llamada cambiado, siempre revertirá el valor de nuevo al valor original, mientras que el almacenamiento de distancia el nuevo valor que se estableció.

Paso la mayor parte de mi tiempo haciendo el desarrollo de control Silverlight ahora, para esta propiedad funciona en WPF y Silverlight-tierra, y no utiliza coercian o nada divertido así. Tal vez consigue que va en el camino correcto, sin embargo.

    /// <summary>
    /// Sets the write-only dependency property.
    /// </summary>
    public string MyWriteOnlyDependencyProperty
    {
        set { SetValue(MyWriteOnlyDependencyPropertyProperty, value); }
    }

    private string _theRealSetValue;

    private bool _ignorePropertyChange;

    /// <summary>
    /// Identifies the MyWriteOnlyDependencyProperty dependency property.
    /// </summary>
    public static readonly DependencyProperty MyWriteOnlyDependencyPropertyProperty =
        DependencyProperty.Register(
            "MyWriteOnlyDependencyProperty",
            typeof(string),
            typeof(TemplatedControl1),
            new PropertyMetadata(null, OnMyWriteOnlyDependencyPropertyPropertyChanged));

    /// <summary>
    /// MyWriteOnlyDependencyPropertyProperty property changed handler.
    /// </summary>
    /// <param name="d">TemplatedControl1 that changed its MyWriteOnlyDependencyProperty.</param>
    /// <param name="e">Event arguments.</param>
    private static void OnMyWriteOnlyDependencyPropertyPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        TemplatedControl1 source = d as TemplatedControl1;
        if (source._ignorePropertyChange)
        {
            source._ignorePropertyChange = false;
            return;
        }
        string value = e.NewValue as string;

        source._theRealSetValue = value;

        // Revert, since this should never be accessible through a read
        source._ignorePropertyChange = true;
        source.SetValue(e.Property, e.OldValue);
    }

Parece que se puede utilizar el CoerceValueCallback asociado a la propiedad a través de la FrameworkPropertyMetadata aplicado en la definición de propiedad de dependencia. Sólo tiene que instalar una devolución de llamada que lleva el segundo argumento, el nuevo valor, se lo entrega al objeto a través de su propio mecanismo de sólo escritura, a continuación, vuelve null (o de los tipos de valor, default(T)).

Es cierto que ".NET recuerda el valor original antes de la coacción", pero no se propagará a través de enlace de datos. Las llamadas a GetValue devolverá el valor coaccionado, que no se escapa nada.

Estoy usando esto para poner en práctica los emisores de conveniencia de un solo sentido para el valor de mi propiedad principal, que es una secuencia de bytes. Un usuario puede unir una cadena, por ejemplo, para establecer la propiedad primaria a los bytes codificados (ASCII o UTF-8, según lo que se establece la propiedad). Pero no todas las secuencias de bytes son válidos UTF-8, por lo que no es posible invertir la conversión y lee una cadena de vuelta a través de la propiedad de conveniencia.

public string AsciiData
{
    set { BinaryArray = Encoding.ASCII.GetBytes(value); }
}

public static readonly DependencyProperty AsciiDataProperty =
    DependencyProperty.Register("AsciiData",
        typeof(string),
        typeof(HexView),
        new FrameworkPropertyMetadata(null, CoerceAsciiData));

private static object CoerceAsciiData(DependencyObject target, object value)
{
    (target as HexView).AsciiData = value as string;
    return null;
}

El controlador de la coacción puede ser eliminado a través de la sustitución de metadatos, así que esto no está proporcionando seguridad , pero evitará que los desarrolladores la creación involuntaria de acoplamiento de mala manera.

Estoy confundido en cuanto a por qué no se puede simplemente tener la 'llegar' nada útil volver?

Pero por otra parte, tal vez simplemente no se implementa el 'OnMyWriteOnlyDependencyPropertyPropertyChanged', en el ejemplo de Jeff.

No hay verdadera razón para tener el evento, si nadie puede leerlo, ¿verdad?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top