2011-11-26 66 views
0

我目前使用下面的代碼被通知當DependencyPropertyValue發生了變化:的DependencyProperty ValueChanging事件

DependencyPropertyDescriptor propDescriptor = DependencyPropertyDescriptor.FromProperty(property, control.GetType()); 
propDescriptor.AddValueChanged(control, controlChangedHandler); 

這個偉大的工程,是相當簡單的,但我現在真的需要的是通知DependencyPropertyValue即將更改。我認爲會有一個DependencyPropertyDescriptor.AddValueChanging()方法,但它似乎並不存在。任何想法如何我可以創建此功能?

我需要能夠取消更改,觸發一些異步後端邏輯,並且只有在後端邏輯成功時纔會更改控件的屬性

+1

我想你混淆的IObservable接口與ICantWaitToF ## kedOver接口...你真的覺得這是一個好主意,允許觀察員抑制性質的變化?我不......你的實際問題是什麼?可能有另一種(乾淨)的方式來滿足你的要求。你可以觀察到你的一個類,還是其他人?你能包住它嗎? – corlettk

+1

@corlettk然後把它看成是強制而不是取消。 'DependencyProperty's有一個'CoerceValueCallback',它允許你在值被實際改變之前採取一些行動,包括取消改變,所以這不是一個壞主意。實際上它是一個非常有用的功能,並且相對乾淨。但是據我所知,你只能在設置'PropertyMetadata'時添加這個回調函數,並且我想在實例化之後執行它。還有其他方法可以做我想做的事情,但我喜歡我提出最好的方法。 – Verax

+0

嗯......不知道。我很難過! DependencyPropertyDescriptor(或PropertyDescriptor)中沒有任何東西允許您吞下事件。我可以用公開的API(這是** UGLY **和兩個大寫的ewe)來進行唯一的破解,就是去除和除去所有其他的觀察者......除了你可能會「破解」現有的描述符使用反射,並鉤住你的強迫......但這一切聽起來都很怪異,我仍然不知道你的實際問題/場景是什麼。 – corlettk

回答

0

我通過在INotifyPropertyChanged實施中實現包裝我的IODevice並將其綁定到DependencyProperty來解決了手頭的問題。

神奇的是,IODeviceWrapper.Value的setter實際上並沒有設置值,而是IO。事實證明,當調解員被DependencyProperty調用時,它必然會發生變化,但尚未提交給DependencyProperty的值。因此,IODeviceWrapper.Value的設置者被DependencyProperty的sudo-不存在的ValueChanging事件調用。

此時,如果DependencyPropertyValue的讀數中讀取,它將獲得舊值直到IO完成。當IO完成時IODeviceWrapper.ValuePropertyChanged事件被觸發,然後DependencyProperty讀取新值。

我的有缺陷的設計現在工作完美無缺。這是代碼,以防其他人感興趣。忽略反對者。

public class IODeviceWrapper : INotifyPropertyChanged 
{ 
    public IODeviceWrapper(IODevice ioDevice) 
    { 
     _ioDevice = ioDevice; 

     _ioDevice.ValueChanged += ValueChanged; 
    } 

    private IODevice _ioDevice; 

    public event PropertyChangedEventHandler PropertyChanged; 

    private void ValueChanged() 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs("Value")); 
     } 
    } 

    public int Value 
    { 
     get { return _ioDevice.Value; } 
     set 
     { 
      //Do ansynchronous IO 
      Task task = new Task(() => _ioDevice.DoIO(value)); 
      task.Start(); 
     } 
    } 
} 
相關問題