Как я могу создать собственное * свойство только для записи * зависимости?

Мне нужно знать, какова процедура создания свойства зависимости только для записи. Я вижу, что класс DependencyProperty не имеет специального "Регистр" метод для свойств только для записи, но я понятия не имею, может ли метод RegisterAttached применяться к тому, что я пытаюсь сделать.

Это свойство должно быть свойством зависимости, а не простым свойством CLR. Внутренне мой класс требует PropertyChangedCallback для этого свойства, чтобы оставаться стабильным.

Я знаю, что могут быть созданы свойства зависимости только для записи, потому что это довольно четко указано в:

Pro C # 2008 и платформа .NET 3.5, стр. 1061.

Тем не менее, это единственное место, где я могу даже найти "свойство зависимости " а также "только пиши на той же странице. И этот автор, по-видимому, не думал, что на самом деле необходимо показывать читателю процедуру для чего-либо, кроме базового свойства зависимости чтения-записи. Конечно, эта книгамог быть грузом BS - но эта книга выглядит довольно стандартно, так что я думаю, чтодовольно уверенная ставка на то, что автор прав. Я предполагаю, что недостаток информации в интернете проистекает из того факта, что вообще никому не нужно создавать такую собственность.

Я знаю, звучит очень сомнительно, если вы хотите создать собственное свойство зависимости только для записи. Уверяю вас, имеет смысл, где я этого хочу. У моего класса есть свойство, значение которого полезно только для объекта, его устанавливающего. Если бы другой объект запросил значение этого свойства позже, он бы нене может иметь никакого рационального смысла в значении, не зная оригинального контекста сеттера.

Это свойство не предназначено для использования в информационных целях. Разрешение сторонним объектам пытаться использовать значение свойства таким способом проблематично, опасно и представляет угрозу безопасности. Поэтому я считаю, что лучший дизайн - запретить операции чтения для этого свойства. Любой, кто использует мой класс, обнаружит, что он вынужден использовать класс так, как он задумывался, что в итоге получится намного лучше и чище.

 Steffen Opel01 сент. 2009 г., 11:00
Он нене выбирай мой ответ, он просто неНе посещал сайт как минимум 2 дня, поэтому он был автоматически принят после окончания периода вознаграждения (вы можете увидеть это, наведя курсор на галочку: автоматическое принятие дает только половину вознаграждения). Я думаю, что оба наших ответа внесли свой вклад в тему, ставя под сомнениеофициальный» Кстати, и вы предлагаете потенциальный обходной путь до сих пор. Система вознаграждений просто не достаточно гибкая, чтобы приспособиться к этому прямо сейчас (среди некоторых других спорных вопросов, см.meta.stackexchange.com/questions/tagged/bounty).
 Jeff Wilcox25 авг. 2009 г., 02:56
Очень интересно услышать, каков реальный сценарий на этом. Ты говоришь "рискованный,» Я думаю "дерьмо это запустит ядерное оружие, если сеттер называетсявот я и хочу услышать больше!
 Jeff Wilcox31 авг. 2009 г., 19:23
Вы спрашивали "как я могу создать противони существуют?, Это'немного беспокоит, что вы выбрали "Это'не возможно " ответ за "Вот'Как реализовать ваш сценарий? ответ.

Ответы на вопрос(4)

Интересно, это определенно редкий сценарий, яМне было бы интересно узнать больше о том, что это позволяет.

Рассматриваете ли вы идею предоставления недопустимого значения (например, null) для чтения через привязку или GetValue, при этом просто не имея получателя CLR?

Либо используйте частный DependencyProperty для хранения "реальный» ценность, о которой вы заботитесь,или же просто личная переменная-член.

В обратном вызове измененного свойства всегда возвращайте значение обратно к исходному значению, сохраняя при этом новое значение, которое было установлено.

Сейчас я трачу большую часть своего времени на разработку элементов управления Silverlight, поэтому это свойство работает в WPF и Silverlight-land и неНе используйте Coercian или что-нибудь веселое, как это. Может быть, это заставит вас идти по правильному пути.

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

    private string _theRealSetValue;

    private bool _ignorePropertyChange;

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

    /// 
    /// MyWriteOnlyDependencyPropertyProperty property changed handler.
    /// 
    /// TemplatedControl1 that changed its MyWriteOnlyDependencyProperty.
    /// Event arguments.
    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);
    }
 Giffyguy28 авг. 2009 г., 20:59
source.SetValue (e.Property, e.OldValue); Будет ли эта строка вызыватьOnMyWriteOnlyDependencyPropertyPropertyChanged» обратный звонок также? Такое ощущение, что это может создать бесконечный цикл. Но я'я не уверен, что этов этом дело.
 Jeff Wilcox22 авг. 2009 г., 09:53
Я не собираюсь набирать очки репутации, придумываяЯ хотел бы услышать, что другие люди думают там в первую очередь. Должно быть, некоторые эксперты WPF вокруг! Я на самом деле владею книгой и тоже растерялся!
 Ben Voigt12 июн. 2014 г., 19:31
Это хакерский способ сделать это. Разве принудительный обратный вызов не существовал еще в 2009 году?
 Jeff Wilcox28 авг. 2009 г., 21:12
Вы'верно: я забыл добавить вызов ignorePropertyChange = true прямо перед SetValue. Обновил мой ответ.
 Jeff Wilcox17 июл. 2014 г., 19:01
Silverlight! = WPF много лет назад, и все еще обладает другим набором функций, включая отсутствие принуждения.

я не понимаю, почему вы можетепростополучить' вернуть ничего полезного?

Но, кроме того, возможно, вы просто нереализоватьOnMyWriteOnlyDependencyPropertyPropertyChanged»в Джеффепример.

Нет реальной причины для проведения мероприятия, если никто не может его прочитать, верно?

 Noon Silk25 авг. 2009 г., 06:21
Таким образом, вы должны активно остановить их от вызова .GetValue ()? Или ты можешь просто не писать геттер? Я'Кстати, я действительно заинтересован в том, что он держит, только если есть другой способ обойти это.
 Noon Silk25 авг. 2009 г., 02:51
Но кто вызывает GetValue? Сам? Или какой-то контроль он не делаетне может контролировать?
 Jeff Wilcox25 авг. 2009 г., 02:49
Без изменений, чтобы забить. Однако существуют ситуации с привязкой данных (или в любом коде!), Когда вы можете вызвать GetValue вместо использования метода получения CLR. Это'почемуОчень важно НЕ помещать код в получатель / установщик CLR для ваших свойств DependencyProperties.
 Noon Silk25 авг. 2009 г., 02:58
Я знаю, в теории мы нене знаю, но яЯ просто говорю в этомконкретный случайКто-нибудь это так называет? Или вы предлагаете, что под капотом иногда фреймворк будет вызывать метод, а иногда - свойство?
 Jeff Wilcox25 авг. 2009 г., 02:56
В том-то и дело - вы никогда не знаете, кто вызывает GetValue: - / that 'Например, почему недопустимое значение, вероятно, лучше, чем последнее установленное значение.
 Giffyguy25 авг. 2009 г., 08:21
Я должен остановить их от вызова GetValue (), так как это свойство зависимости. Но если это можетне будет сделано, как предлагали другие, тогда яЯ должен заставить GetValue () возвращать явно бесполезное фиктивное значение.
 Giffyguy25 авг. 2009 г., 06:11
Другие элементы управления, созданные другими разработчиками, будут иметь прямой доступ к этому свойству. Я могу'не позволяют им пытаться использовать это свойствоценность для всего. Им никогда не будет безопасно делать это.

Похоже, вы можете использоватьCoerceValueCallback связано с собственностью черезFrameworkPropertyMetadata применяется в определении свойства зависимости. Просто установите функцию обратного вызова, которая принимает второй аргумент, новое значение, передает его объекту через собственный механизм только для записи, а затем возвращаетnull (или для типов значений,default(T)).

Это'это правда, что ".NET запоминает первоначальное значение до принуждения ", но это победилоне может распространяться через привязку данных. Звонки вGetValue вернет приведенное значение, которое неЯ ничего не пропускаю.

Я использую это для реализации однонаправленных установщиков удобства для значения моего основного свойства, которое представляет собой последовательность байтов. Пользователь может связать строку, например, чтобы установить первичное свойство для закодированных байтов (ASCII или UTF-8, в зависимости от того, какое свойство установлено). Но не все байтовые последовательности являются допустимыми UTF-8, поэтомуМожно отменить преобразование и прочитать строку обратно через удобное свойство.

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 HexV,iew).AsciiData = value as string;
    return null;
}

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

Решение Вопроса

Вы можете'т, это похоже на дизайн. Хотя я понимаю ваш подход к упомянутой книге и никоим образом не подвергаю сомнению ее качество, яя все еще могу предположить, что это какая-то копиявставить или аналогичный вопрос. Вот мои рассуждения:

Код системы свойств WPF

Как вы уже упоминали, публичный APIКласс DependencyProperty только особенностиRegisterReadOnly () а такжеRegisterAttachedReadOnly ().Speluncing в классе внутренних дел черезрефлектор только показывает выделенный код для обработки этихСвойства зависимостей только для чтения, ничего не видно в отношении функциональности только для записи.Другим вариантом могли быть метаданные, но ниМетаданные свойства зависимости ни в частностиМетаданные рамочного свойства с помощьюFrameworkPropertyMetadataOptions Перечисление предоставляет что-нибудь по принципу только для записи.

Проект системы собственности WPF

Более важный, 'Текущая реализация WPF его процессора XAML по своей природе осведомлена о свойстве зависимостей. Процессор WPF XAML использует системные методы свойств для свойств зависимостей при загрузке двоичного XAML и обработке атрибутов, которые являются свойствами зависимостей. Это эффективно обходит свойства оболочки., увидетьСвойства загрузки и зависимости XAML.Самое важное, 'Свойства зависимости, как правило, следует рассматривать как общедоступные свойства. Природа системы свойств Windows Presentation Foundation (WPF) не позволяет создавать гарантии безопасности для значения свойства зависимости. ', увидетьЗависимость Безопасность имущества.

В частности, последние две точки обозначают ограничение проекта, что значения свойств зависимости всегда доступны черезПолучитьЗначение () /SetValue ()независимо от того, являются ли их оболочки CLR ограниченными по доступу или доступны вообще, с единственным исключением, специально учтеннымСвойства зависимостей только для чтения.

Следовательно, какДжеффс ответ уже подразумевает, что, например, просто удаление геттера не мешает кому-либо получить доступ к свойству черезПолучитьЗначение ()хотя это может по крайней мереуменьшить сразу открытое пространство имен пользовательского класса, Полезность любого такого семантического обходного пути, заключающегося в том, чтобы сделать значение свойства несколько менее видимым / доступным, а извлеченное значение по своей сути бесполезным для клиентов, как предполагаетДжефф зависит от вашего конкретного сценария, конечно.

Ваш ответ на вопрос