[Wpf] 종속성 속성에서 속성 변경 이벤트를 발생시키는 방법?


Answers

클래스에서 서비스에서 관련 데이터를 가져 오기 위해 이벤트를 수신 대기하도록하는 종속성 속성이있는 비슷한 문제가 발생했습니다.

public static readonly DependencyProperty CustomerProperty = 
    DependencyProperty.Register("Customer", typeof(Customer),
        typeof(CustomerDetailView),
        new PropertyMetadata(OnCustomerChangedCallBack));

public Customer Customer {
    get { return (Customer)GetValue(CustomerProperty); }
    set { SetValue(CustomerProperty, value); }
}

private static void OnCustomerChangedCallBack(
        DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
    CustomerDetailView c = sender as CustomerDetailView;
    if (c != null) {
        c.OnCustomerChanged();
    }
}

protected virtual void OnCustomerChanged() {
    // Grab related data.
    // Raises INotifyPropertyChanged.PropertyChanged
    OnPropertyChanged("Customer");
}
Question

좋아요, 그래서 저는이 두 가지 속성을 가진 컨트롤을 가지고 있습니다. 이 중 하나는 DependencyProperty이고 다른 하나는 첫 번째 별칭입니다. 내가 할 수 있어야 할 첫 번째 변경 될 때 두 번째 (별칭) PropertyChanged 이벤트를 발생시키는 것입니다.

참고 : DependencyObjects, INotifyPropertyChanged 않습니다 (내 컨트롤이 하위 클래스 ListView 때문에 작동하지 않았다) 사용하고 있습니다.

이 같은.....

protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
{
    base.OnPropertyChanged(e);
    if (e.Property == MyFirstProperty)
    {
        RaiseAnEvent( MySecondProperty ); /// what is the code that would go here?
    }    
}

내가 이런 식으로 할 수있는 INotify를 사용한다면 ...

public string SecondProperty
{
    get
    {
        return this.m_IconPath;
    }
}

public string IconPath
{
    get
    {
        return this.m_IconPath;
    }
    set
    {
        if (this.m_IconPath != value)
        {
            this.m_IconPath = value;
        this.SendPropertyChanged("IconPath");
        this.SendPropertyChanged("SecondProperty");
        }
    }
}

한 Setter에서 여러 속성에 대해 PropertyChanged 이벤트를 발생시킬 수 있습니다. DependencyProperties 만 사용하여 동일한 작업을 수행 할 수 있어야합니다.




나는 Sam과 Xaser에 동의하고 이것을 조금 더 멀리 가져 갔다. UserControl에서 INotifyPropertyChanged 인터페이스를 구현해야한다고 생각하지 않습니다. 컨트롤은 이미 DependencyObject이므로 이미 알림이 제공됩니다. DependencyObject에 INotifyPropertyChanged를 추가하는 것은 불필요하며 "냄새"가납니다.

내가 한 것은 Sam이 제안한 것처럼 DependencyProperties로 두 속성을 모두 구현하지만 "첫 번째"종속성 속성의 PropertyChangedCallback을 사용하여 "두 번째"종속성 속성의 값을 변경했습니다. 둘 다 종속성 속성이므로 둘 다 자동으로 변경된 알림을 관심있는 구독자 (예 : 데이터 바인딩 등)에게 보냅니다.

이 경우 종속성 속성 A는 InviteText 문자열로, 종속성 속성 B, ShowInvite라는 Visibility 속성이 변경됩니다. 데이터 바인딩을 통해 컨트롤에서 완전히 숨길 수 있도록하려는 일부 텍스트가 있으면 일반적인 사용 사례입니다.

    public string InviteText  
    {
        get { return (string)GetValue(InviteTextProperty); }
        set { SetValue(InviteTextProperty, value); }
    }

    public static readonly DependencyProperty InviteTextProperty =
        DependencyProperty.Register("InviteText", typeof(string), typeof(InvitePrompt), new UIPropertyMetadata(String.Empty, OnInviteTextChanged));

    private static void OnInviteTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        InvitePrompt prompt = d as InvitePrompt;
        if (prompt != null)
        {
            string text = e.NewValue as String;
            prompt.ShowInvite = String.IsNullOrWhiteSpace(text) ? Visibility.Collapsed : Visibility.Visible;
        }
    }

    public Visibility ShowInvite
    {
        get { return (Visibility)GetValue(ShowInviteProperty); }
        set { SetValue(ShowInviteProperty, value); }
    }

    public static readonly DependencyProperty ShowInviteProperty =
        DependencyProperty.Register("ShowInvite", typeof(Visibility), typeof(InvitePrompt), new PropertyMetadata(Visibility.Collapsed));

참고 UserControl 시그니처 나 생성자는 특별한 것이 없으므로 여기에 포함하지 않습니다. 그들은 INotifyPropertyChanged에서 전혀 서브 클래스 할 필요가 없습니다.