3

我試圖實現一個WPF ViewModel使用城堡溫莎動態代理。我的想法是我想提供一個接口(下面的IPerson應該足夠作爲一個例子),一個具體的支持類和一個攔截器(用於提供INotifyPropertyChanged的自動實現)。攔截器的實現在這裏:http://www.hightech.ir/SeeSharp/Best-Implementation-Of-INotifyPropertyChange-Ever城堡溫莎代理,隱式接口和WPF綁定

我看到的問題是,當我將我的模型綁定到WPF控件時,控件看不到模型實現INotifyPropertyChanged。我相信(但不確定),這是因爲Windsor正在明確地實現接口,而WPF似乎期望它們是隱含的。

有什麼辦法可以使這個工作,使模型的變化被攔截器捕獲並提升到模型?

庫的所有版本都是最新的:Castle.Core 2.5.1.0和2.5.1.0溫莎

代碼如下:

// My model's interface 
public interface IPerson : INotifyPropertyChanged 
{ 
    string First { get; set; } 
    string LastName { get; set; } 
    DateTime Birthdate { get; set; } 
} 

// My concrete class: 
[Interceptor(typeof(NotifyPropertyChangedInterceptor))] 
class Person : IPerson 
{ 
    public event PropertyChangedEventHandler PropertyChanged = (s,e)=> { }; 
    public string First { get; set; } 
    public string LastName { get; set; } 
    public DateTime Birthdate { get; set; } 
} 

// My windsor installer 
public class Installer : IWindsorInstaller 
{ 
    public void Install(IWindsorContainer container, IConfigurationStore store) 
    { 
     container.Register(
      Component.For<NotifyPropertyChangedInterceptor>() 
      .ImplementedBy<NotifyPropertyChangedInterceptor>() 
      .LifeStyle.Transient); 
     container.Register(
      Component.For<IPerson, INotifyPropertyChanged>() 
      .ImplementedBy<Person>().LifeStyle.Transient); 
    } 
} 

回答

4

因此,答案竟然是相當簡單的...從http://www.hightech.ir/SeeSharp/Best-Implementation-Of-INotifyPropertyChange-Ever的代碼定義攔截器爲:

public class NotifyPropertyChangedInterceptor : IInterceptor 
{ 
    private PropertyChangedEventHandler _subscribers = delegate { }; 

    public void Intercept(IInvocation invocation) 
    { 
     if (invocation.Method.DeclaringType == typeof(INotifyPropertyChanged)) 
     { 
      HandleSubscription(invocation); 
      return; 
     } 

     invocation.Proceed(); 

     if (invocation.Method.Name.StartsWith("set_")) 
     { 
      FireNotificationChanged(invocation); 
     } 
    } 

    private void HandleSubscription(IInvocation invocation) 
    { 
     var handler = (PropertyChangedEventHandler)invocation.Arguments[0]; 

     if (invocation.Method.Name.StartsWith("add_")) 
     { 
      _subscribers += handler; 
     } 
     else 
     { 
      _subscribers -= handler; 
     } 
    } 

    private void FireNotificationChanged(IInvocation invocation) 
    { 
     var propertyName = invocation.Method.Name.Substring(4); 
     _subscribers(invocation.InvocationTarget, new PropertyChangedEventArgs(propertyName)); 
    } 
} 

在我的情況下,InvocationTarget只是不被傳遞作爲第一權實體PropertyChanged的參數(因爲我正在生成一個代理)。將最後一個功能更改爲以下固定問題:

private void FireNotificationChanged(IInvocation invocation) 
{ 
    var propertyName = invocation.Method.Name.Substring(4); 
    _subscribers(invocation.Proxy, new PropertyChangedEventArgs(propertyName)); 
} 
0

我認爲你需要做的的成員實現接口Virtual的類。

+0

這似乎沒有幫助。 – 2011-05-07 04:46:10