繁体   English   中英

将WPF控件绑定到模型对象上动态引入的接口

[英]Binding WPF controls to dynamically introduced interfaces on model objects

我正在使用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路径错误:在'object''ModelObject'(HashCode = 56810243)'上找不到'SomeProperty'属性。 BindingExpression:Path = SomeProperty; DataItem ='ModelObject'(HashCode = 56810243); 目标元素是'TextBlock'(Name =''); 目标属性为“文本”(类型为“字符串”)

作为参考,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类(并将所有成员作为简单的中继实现到组成的ActualDataObject实例),则绑定就可以了,并且SomeProperty会显示无错误。

我遗漏的是IMyInterface的PostSharp实现和我自己的显式版本之间的不同吗?

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

可能的解决方案:

<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}

我设法在这里找到解决此问题的方法: WPF数据绑定到接口而不是实际的对象-可能进行铸造吗?

事实证明,如果绑定是针对接口类型显式定义的,而不是隐式定义的,则绑定将起作用,大概是因为ModelObject没有SomeProperty,但是它确实具有IMyInterface.SomeProperty吗?

因此,这有效;

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

但是,确实会引起设计者警告,如所参考问题中所述。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM