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