0

我正在使用 PostSharp 的 [CompositionAspect] 功能将接口动态注入到我的 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 错误:40:BindingExpression 路径错误:在“对象”“ModelObject”(HashCode=56810243)上找不到“SomeProperty”属性。BindingExpression:Path=SomeProperty; DataItem='ModelObject' (HashCode=56810243); 目标元素是'TextBlock'(名称='');目标属性是“文本”(类型“字符串”)

作为参考,View 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 类(并将所有成员实现为组合的实际数据对象实例的简单中继),那么绑定很好,并且 SomeProperty 显示没有错误。

我错过了 IMyInterface 的 PostSharp 实现和我自己的显式版本之间的不同之处?

4

3 回答 3

1

I managed to find a solution to this problem here: WPF databinding to interface and not actual object - casting possible?

Turns out the binding will work if it is defined explicitly against the interface type, instead of implicitly, presumably because ModelObject does not have a SomeProperty, but it does have IMyInterface.SomeProperty ?

So, this works;

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

Though, it does cause designer warnings, as noted in the referenced question.

于 2012-11-30T01:30:31.193 回答
1

我认为原因是 PostSharp 引入了显式实现,因此实际上没有引入公共属性。您应该使用 [IntroduceInterface] 建议[IntroduceMember] 建议来引入公共属性。

于 2012-11-30T08:09:36.603 回答
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}
于 2012-11-30T00:45:08.673 回答