[wpf] كيفية Raise Property Changed events on a Dependency Property؟



1 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 sub-classed)

شيء من هذا القبيل.....

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

حيث يمكنني رفع الأحداث PropertyChanged على خصائص متعددة من واحد واضعة. أحتاج إلى أن أكون قادرة على فعل الشيء نفسه ، فقط باستخدام DependencyProperties.




وأنا أتفق مع سام وكساسر وقد اتخذوا هذا أبعد قليلا. لا أعتقد أنه يجب عليك تطبيق واجهة INotifyPropertyChanged في UserControl على الإطلاق ... عنصر التحكم بالفعل DependencyObject وبالتالي تأتي بالفعل مع إعلامات. إضافة INOTifyPropertyChanged إلى DependencyObject مكرر و "الروائح" خاطئة بالنسبة لي.

ما فعلته هو تنفيذ كلا الخصائص كـ DependencyProperties ، كما يقترح Sam ، ولكن ببساطة كان PropertyChangedCallback من خاصية التبعية "الأولى" يغير قيمة خاصية التبعية "الثانية". نظرًا لأن كليهما عبارة عن خصائص تبعية ، فسيعمل كلاهما تلقائيًا على زيادة إشعارات التغيير لأي مشتركين مهتمين (مثل ربط البيانات وما إلى ذلك)

في هذه الحالة ، الخاصية التبعية A هي سلسلة InviteText ، والتي تقوم بتشغيل تغيير في الخاصية التبعية B ، الخاصية Visibility المسماة ShowInvite. ستكون هذه حالة استخدام شائعة إذا كان لديك بعض النص الذي تريد أن تكون قادرًا على إخفاءه تمامًا في عنصر تحكم عبر ربط البيانات.

    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 على الإطلاق.




Related



Tags

wpf   binding