2012-11-29 39 views
0

我正在使用PostSharp的[CompositionAspect]功能動態地將接口​​注入到WPF應用程序中的模型對象。然而,似乎WPF無法正確綁定(顯示)屬性,除非相關接口在模型對象上顯式實現?將WPF控件綁定到動態引入的模型對象上的接口

使用自定義CompositionAspect(ComposeObjectAspect)我能夠通過運行時將ModelObject轉換爲引入的接口,直接成功地公開內部IMyInterface對象的屬性;

// some interface definition, for sample completeness 
public interface IMyInterface 
{ 
    public string MyProperty { get; set; } 
} 


// model object, which does NOT implement IMyInterface directly, though the interface is dynamically introduced by PostSharp 
[ComposeObjectAspect(typeof(IMyInterface))] 
public class ModelObject 
{ 
    private IMyInterface actualDataObject; 
} 

. . . 

public class ViewModel 
{ 
    public ObservableCollection<IMyInterface> MyData { get; } 

    public void LoadData() 
    { 
     // concrete IMyInterface dtos are returned here, and put into a VM collection 
     IList<IMyInterface> myData = 
      (from IMyInterface o in SomeDataSource.LoadLocalDescriptors() 
      select new ModelObject(o) as IMyInterface).ToList(); 
     this.MyData = new ObservableCollection<IMyInterface>(myData); 
    } 
} 

這一切工作正常,如果我檢查的myData的列表中的任何物體,或者將其轉換爲類型IMyInterface的(正如你可以看到形成類ModelObject定義的上方不直接實現),我可以直接從actualDataObject中查看內部屬性。這一切都很好。

現在,當我嘗試將ViewModel.Data集合綁定到WPF數據網格時,出現一系列綁定錯誤,如:

System.Windows.Data Error: 40 : BindingExpression path error: 'SomeProperty' property not found on 'object' ''ModelObject' (HashCode=56810243)'. BindingExpression:Path=SomeProperty; DataItem='ModelObject' (HashCode=56810243); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')

作爲參考,查看XAML的相關部分看起來像;

<DataGrid ItemsSource="{Binding MyData}" AutoGenerateColumns="False"> 
    <DataGrid.Columns> 
     <DataGridTextColumn Width="Auto" Header="Some Property" Binding="{Binding SomeProperty, Mode=OneWay}" /> 
    </DataGrid.Columns> 
</DataGrid> 

雖然所有的數據行都是可見的(而且是空的),但它是空白的網格列。

如果我檢查'ModelObject',那麼屬性IMyInterface.SomeProperty就在那裏。

如果我直接將IMyInterface應用於ModelObject類(並將所有成員實現爲組成actualDataObject實例的簡單中繼),那麼綁定是正常的,並且SomeProperty顯示沒有錯誤。

我錯過了IMyInterface的PostSharp實現和我自己的顯式版本之間有什麼不同?

+0

嗯..有趣。你可以發佈你的xaml嗎? – Robin

+0

@Robin;完成,雖然它非常簡單;那裏沒什麼不尋常的。 –

+0

「MyData」屬性在哪裏? –

回答

0

我設法找到一個解決這個問題就在這裏:WPF databinding to interface and not actual object - casting possible?

原來的綁定將工作,如果它明確反對定義接口類型,而不是隱含的,大概是因爲ModelObject沒有SomeProperty,但它確實有IMyInterface.SomeProperty?

所以,這個工作;

<DataGridTextColumn Width="Auto" Header="Some Property" 
     Binding="{Binding Path=(mynamespace:IMyInterface.SomeProperty), Mode=OneWay}" /> 

雖然它確實會引起設計師警告,如引用問題中所述。

0

可能的解決方案:

<DataGrid DataContext="{Binding Data}" ItemsSource="{Binding}" AutoGenerateColumns="False"> 
    <DataGrid.Columns> 
     <DataGridTextColumn Width="Auto" Header="Some Property" Binding="{Binding SomeProperty, Mode=OneWay}" /> 
    </DataGrid.Columns> 
</DataGrid> 

<DataGridTextColumn Width="Auto" Header="Some Property" Binding="{Binding Path=actualDataObject.SomeProperty, Mode=OneWay} 
+0

我沒有看到這個改變希望達到什麼目的,但是對於我所嘗試的笑聲 - 同樣的結果。 –

+0

MyData應該有{get;設置:} –

+0

不,這是不相關的,因爲問題是顯示,並且行對象的綁定是OneWay。 –

1

我認爲原因是PostSharp引入了一個顯式的實現,所以實際上沒有公共屬性被引入。您應該使用[IntroduceInterface]建議 [IntroduceMember]建議來介紹公共屬性。

相關問題