문제

쓰기 전용 종속성 속성을 만드는 절차가 무엇인지 알아야 합니다.종속성 속성 클래스에는 쓰기 전용 속성에 대한 특별한 "Register" 메서드가 없다는 것을 알 수 있지만 RegisterAttached 메서드가 내가 수행하려는 작업에 적용될 수 있는지 여부는 알 수 없습니다.

이 속성은 단순한 CLR 속성이 아닌 종속성 속성이어야 합니다.내부적으로 내 클래스에서는 안정성을 유지하기 위해 이 속성에 대한 PropertyChangedCallback이 필요합니다.

다음 항목에 매우 명확하게 명시되어 있기 때문에 쓰기 전용 종속성 속성을 생성할 수 있다는 것을 알고 있습니다.
Pro C# 2008 및 .NET 3.5 플랫폼, 페이지 1061.
그러나 이것은 같은 페이지에서 "종속성 속성"과 "쓰기 전용"을 찾을 수 있는 유일한 곳입니다.그리고 이 저자는 기본 읽기-쓰기 종속성 속성 이외의 다른 절차를 독자에게 실제로 보여줄 필요가 없다고 생각한 것 같습니다.물론 이 책은 ~할 수 있었다 학사가 많을 수도 있지만 이 책은 꽤 평범해 보이기 때문에 저자의 말이 맞을 가능성이 매우 높다고 생각합니다.나는 인터넷에 정보가 부족한 이유는 일반적으로 누구도 이와 같은 자산을 만들 필요가 없다는 사실에서 비롯된다고 생각합니다.

자신만의 쓰기 전용 종속성 속성을 만드는 것이 매우 의심스럽다는 것을 알고 있습니다.내가 원하는 곳에는 의미가 있다고 확신합니다.내 클래스에는 해당 값을 설정하는 개체에만 유용한 속성이 있습니다.나중에 다른 개체가 이 속성의 값을 요청하는 경우 setter의 원래 컨텍스트를 알지 못하면 값을 합리적으로 이해할 수 없습니다.

이 속성은 정보 제공 목적으로 사용되지 않습니다.외부 개체가 이러한 방식으로 속성 값을 사용하도록 허용하는 것은 문제가 있고 위험하며 보안 위험이 있습니다.따라서 저는 이 속성에 대한 읽기 작업을 금지하는 것이 가장 좋은 디자인이라고 생각합니다.내 수업을 사용하는 사람은 누구나 의도한 대로 수업을 사용해야 한다는 사실을 알게 될 것이며, 결국에는 훨씬 더 좋고 깔끔하게 작동할 것입니다.

도움이 되었습니까?

해결책

당신은 할 수 없습니다. 이것은 디자인으로 보입니다. 언급 된 책에 대한 귀하의 접근 방식을 이해할 수 있고 그 품질에 의문을 제기하지는 않지만, 나는 이것을 일종의 복사 및 붙여 넣기 또는 이와 유사한 문제라고 생각합니다. 여기 내 추론이 있습니다.

WPF 속성 시스템 코드

WPF 속성 시스템 설계

  • 더 중요, 'XAML 프로세서의 현재 WPF 구현은 본질적으로 종속성 속성 인식입니다. WPF XAML 프로세서는 바이너리 XAML을로드 할 때 종속성 속성에 대한 속성 시스템 방법을 사용하고 종속성 특성 인 처리 속성을 사용합니다. 이것은 효과적으로 속성 포장지를 우회합니다. ', 보다 XAML 로딩 및 종속성 특성.
  • 가장 중요한, '종속성 속성은 일반적으로 공개 속성으로 간주되어야합니다. WPF (Windows Presentation Foundation) 속성 시스템의 특성은 종속성 속성 값에 대한 보안 보장 능력을 방지합니다. ', 보다 의존성 속성 보안.

특히 후자의 두 지점은 디자인 제약 조건을 요약하고 있으며, 종속성 속성 값은 항상 getValue ()/setValue (), CLR 포장지가 액세스 제한이든 전혀 사용 가능하든, 구체적으로 설명 된 유일한 예외는 읽기 전용 종속성 속성.

결과적으로 제프스 답변은 이미 getter를 제거하는 것만으로도 실제로 재산에 액세스하는 사람을 방해하지 않습니다. getValue (), 그러나 이것은 적어도 적어도 할 수 있습니다 '사용자 정의 클래스의 즉시 노출 된 네임 스페이스 감소'. 부동산 가치를 다소 눈에 띄지 않거나 접근하기 쉽고 검색된 가치를 내장하는 데 도움이되는 시맨틱 해결 방법의 유용성. 제프 물론 특정 시나리오에 따라 다릅니다.

다른 팁

흥미 롭습니다. 이것은 확실히 드문 시나리오입니다. 나는 그것이 가능하게하는 것에 대해 더 많이 듣고 싶습니다.

CLR getter가없는 동안 바인딩 또는 getValue를 통해 읽기에 대한 유효하지 않은 값 (예 : NULL)을 제공한다는 아이디어를 고려 하시겠습니까?

개인 의존성 전문가를 사용하여 신경 쓰는 "실제"값을 저장하십시오. 또는 개인 회원 변수.

속성이 변경된 콜백에서는 항상 값을 원래 값으로 되돌리고 설정된 새 값을 저장하십시오.

나는 대부분의 시간을 Silverlight Control Development에서 지금 보낸다. 그래서이 부동산은 WPF와 Silverlight-Land에서 작동하며 Conercian이나 그와 같은 재미있는 것을 사용하지 않습니다. 어쩌면 그것은 당신이 올바른 길을 가게 할 수도 있습니다.

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

를 이용하시면 될 것 같습니다 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 HexView).AsciiData = value as string;
    return null;
}

강제 처리기는 메타데이터 교체를 통해 제거될 수 있으므로 이는 제공되지 않습니다. 보안, 하지만 개발자가 실수로 잘못된 방식으로 결합을 생성하는 것을 방지할 수 있습니다.

왜 당신이 '얻기'를받을 수없는 이유에 대해 혼란 스러워요.

그러나 아마도 Jeff의 예에서 'OnmyWriteOnlyDependencyPropertyProperTyChanged'를 구현하지 않을 것입니다.

아무도 읽을 수 없다면 이벤트를 가야 할 실제 이유가 없습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top