2017-10-05 34 views
0

我有一個帶有PropertyChangedCallback的依賴屬性的自定義控件。該屬性的值可能會從自定義控件的邏輯中或從無(通過用戶交互或通過從客戶端應用程序設置的值)更改。PropertyChangeCallback - 是否在控制範圍內進行更改

有沒有一種方法可以告訴哪些導致財產改變?

我試着看着「發件人」,但在每種情況下,發件人都是自定義控件本身。

舉例說明:

public static readonly DependencyProperty SelectedTimeProperty = 
     DependencyProperty.Register("SelectedTime", typeof(DateTime?), typeof(TimePickerControl), new PropertyMetadata(null, new PropertyChangedCallback(HandleSelectedTimeChanged))); 

    public static readonly DependencyProperty HoursProperty = 
     DependencyProperty.Register("Hours", typeof(object), typeof(TimePickerControl), new PropertyMetadata(@"", (o, e) => ((TimePickerControl)o).OnHoursChanged(o, e.OldValue))); 

    public static readonly DependencyProperty MinutesProperty = 
     DependencyProperty.Register("Minutes", typeof(object), typeof(TimePickerControl), new PropertyMetadata(@"", (o, e) => ((TimePickerControl)o).OnMinutesChanged(o, e.OldValue))); 

    public static readonly DependencyProperty SecondsProperty = 
     DependencyProperty.Register("Seconds", typeof(object), typeof(TimePickerControl), new PropertyMetadata(@"", (o, e) => ((TimePickerControl)o).OnSecondsChanged(o, e.OldValue))); 

所以客戶端應用程序既可以更新SelectedTime,在這種情況下HoursMinutesSeconds將由控制進行更新。該邏輯在HandleSelectedTimeChanged中處理。

然而,用戶還可以修改Hours之一,MinutesSeconds其中SelectedTime就必須進行相應的更新。

正如您大概猜測的那樣,這會創建一個循環,因爲例如Hours的更改會導致SelectedTime回調被觸發,這當然會更改調用其回調的小時/分鐘/秒再次觸發。

我想要麼只調用回調,如果改變來自控制之外,或者在回調中檢測到這一點,所以直接退出。

我到目前爲止唯一的想法是在更改其中一個屬性之前設置一個私有變量,並在其回調出口內設置,然後在更改後立即清理它,但這看起來很雜亂對我來說。有沒有更好的方法來做到這一點?

+0

依賴項屬性在控件中。如果你也在控制中改變它們的值,那麼只需使用一些標誌:在改變之前設置它,在回調中檢查它。另一件事是[強制](https://docs.microsoft.com/en-us/dotnet/framework/wpf/advanced/dependency-property-callbacks-and-validation#coerce-value-callbacks-and-property-changed -events)。 – Sinatr

+1

_「你可能會猜到,這會產生一點循環」_這不應該發生。只有在屬性值_actually changes_時,纔會調用屬性更改回調。因此,如果您更改'Hours'屬性,則其回調大概會設置SelectedTime屬性,該屬性將再次設置「Hours」屬性值。但是,'Hours'屬性值沒有改變,所以它的屬性改變了回調函數將不會被調用。我懷疑你的問題更多地與你的'Hours','Minutes'和'Seconds'依賴屬性聲明爲類型**對象**有關。他們應該是** int **嗎? –

+0

@StevenRands - 這不是一個無限循環,我意識到你在說什麼,但它創造了一個複雜的意大利麪條流,這使得讀取/調試/維護變得困難,並且可能導致控制中的其他問題。 – colmde

回答

0

至於只從外面發射變化事件,恐怕是不可能的。 這是一種非常常見的情況,您正面臨着一些解決方案。

  1. 第一個也是最好的解決方案是完全避免這種情況。

在您的情況下,它是指取代具有的時間每個組件多重依賴性性質只寫爲每個自定義值轉換器,然後將值綁定到所述單個SelectedTime屬性與所需的轉換器。我個人高度推薦這種方法。

  1. 第二種方法是根據需要進行更改。

在你的情況下,這意味着在觸發之前UpdateHour檢查是否應該更新小時。如果不是不觸發它。這是一個乾淨的方法,將會削減更新的循環,但是會有性能開銷。

  1. 第三種方法是有髒標誌。

這有點像你說的。對於SelectedDate,您保留一個布爾標誌,其值爲false。當它發生變化時,將其設置爲true,並在下一個循環中如果它爲true,則退出並將其設置爲false。

正如你所說,它是凌亂和不潔。但完成工作。

+0

爲什麼downvote?謹慎發表評論? – Emad

+1

我用「骯髒的旗幟」的方法... – colmde