Question

Je dois savoir ce que la procédure est de faire une dépendance-propriété en écriture seule. Je peux voir que la classe DependencyProperty ne dispose pas d'une méthode spéciale « Register » propriétés en écriture seule, mais je ne sais pas si la méthode RegisterAttached peut demander à ce que je suis en train de faire.

Cette propriété doit être une dépendance-propriété, plutôt qu'une simple propriété CLR. En interne, ma classe a besoin d'un PropertyChangedCallback sur cette propriété afin de rester stable.

Je sais que les propriétés de dépendance-écriture ne peuvent être créés, car il est dit très clairement dans:
Pro C # 2008 et la plate-forme .NET 3.5 page 1061 .
Cependant, c'est le seul endroit où je peux même trouver « propriété de dépendance » et « écrire uniquement » sur la même page. Et cet auteur ne semble pas jugé nécessaire de montrer effectivement le lecteur la procédure de rien d'autre qu'une dépendance-propriété en lecture-écriture de base. Bien sûr, ce livre pourrait être une charge de BS - mais ce livre semble assez standard, donc je pense que c'est un pari assez sûr que l'auteur est correct. Je suppose que le manque d'information sur Internet provient du fait que personne ne doit généralement faire une propriété comme celui-ci.

Je sais que cela semble très discutable de vouloir faire votre propre dépendance-propriété en écriture seule. Je vous assure qu'il est logique où je veux. Ma classe a une propriété dont la valeur est utile uniquement à l'objet de l'activation. Si un autre objet était de demander la valeur de ce bien plus tard, il ne serait pas en mesure de donner un sens rationnel de la valeur sans connaître le contexte original du compositeur.

Cette propriété est pas destiné à être utilisé à des fins d'information. Laisser des objets à l'extérieur tentent d'utiliser la valeur de la propriété de cette façon est problématique, dangereux et un risque de sécurité. Je crois donc que la meilleure conception est d'interdire les opérations de lecture sur cette propriété. Toute personne qui utilise ma classe trouveront qu'ils sont contraints d'utiliser la classe comme il était prévu, qui fonctionnera beaucoup mieux et plus propre à la fin.

Était-ce utile?

La solution

Vous ne pouvez pas, cela semble être par la conception. Même si je peux comprendre votre approche du livre mentionné et je suis en aucun cas remettre en question sa qualité, je suppose que ce encore être une sorte de copier-coller ou d'émission similaire. Voici mon raisonnement:

WPF code système de propriété

WPF conception du système de propriété

En particulier, les deux derniers points sont Décrivant la contrainte de conception, que les valeurs de propriété de dépendance sont toujours accessibles via GetValue () / SetValue () , peu importe si leurs emballages CLR sont un accès restreint ou disponibles à tous, à la seule exception étant le représenté spécifiquement pour en lecture seule des propriétés de dépendance .

Par conséquent, comme Jeffs réponse implique déjà, juste enlever le getter par exemple n'empêche pas vraiment quiconque accède à la propriété via GetValue () , bien que cela peut au moins réduire l'espace de noms exposé immédiatement d'une classe personnalisée '. L'utilité d'une telle solution de contournement sémantique de faire la propevaleur rty un peu moins visible / accessible et la valeur récupérée par nature inutile pour les clients comme suggéré par Jeff dépend de votre scénario particulier bien sûr.

Autres conseils

Intéressant, c'est vraiment un scénario rare, je serais intéressé d'en savoir plus dans ce qu'elle permet.

Envisageriez-vous l'idée de fournir une valeur non valide (comme nul) pour lit par la liaison ou GetValue, tout simplement ne pas avoir un getter CLR?

Soit utiliser un DependencyProperty privé pour stocker la valeur "réelle" que vous aimez, ou juste une variable de membre privé.

Dans la propriété de rappel a changé, toujours revenir la valeur à la valeur d'origine, tout en stockant loin la nouvelle valeur qui a été réglée.

Je passe la plupart de mon temps à faire du développement de Silverlight contrôle maintenant cette propriété fonctionne dans WPF et Silverlight terre, et ne pas utiliser quoi que ce soit amusant coercian ou comme ça. Peut-être que vous allez obtient sur la bonne voie, cependant.

    /// <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);
    }

Il semble que vous pouvez utiliser le CoerceValueCallback associé à la propriété via le FrameworkPropertyMetadata appliqué dans la définition de la propriété de dépendance. Il suffit d'installer un rappel qui prend le deuxième argument, la nouvelle valeur, il passe à l'objet via votre propre mécanisme d'écriture seule, puis retourne null (ou pour les types de valeur, default(T)).

Il est vrai que « .NET se souvient de la valeur d'origine avant la coercition », mais il ne sera pas se propager par l'intermédiaire de liaison de données. Les appels à GetValue renverra la valeur sous la contrainte, qui ne fuit pas quoi que ce soit.

J'utilise ceci pour mettre en œuvre un sens setters de commodité pour la valeur de ma propriété principale, qui est une séquence d'octets. Un utilisateur peut se lier à une chaîne de caractères, par exemple, pour définir la propriété primaire aux octets codés ASCII (ou UTF-8, en fonction de ce que la propriété est définie). Mais pas toutes les séquences d'octets sont valides UTF-8, donc il est impossible d'inverser la conversion et de lire une chaîne à travers la propriété de commodité.

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;
}

Le gestionnaire de contrainte peut être retirée par le remplacement des métadonnées, donc ce ne fournit pas sécurité , mais il évitera aux développeurs de créer accidentellement couplage dans les mauvaises façons.

Je suis confus quant à pourquoi vous ne pouvez pas avoir juste rien « obtenir » retour utile?

Mais de plus, peut-être que vous venez de ne reconnaissent pas la « OnMyWriteOnlyDependencyPropertyPropertyChanged », dans l'exemple de Jeff.

Aucune raison d'avoir l'événement, si personne ne peut le lire, non?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top