WPF与内部setter的双向绑定

时间:2016-11-13 07:29:54

标签: wpf data-binding internalsvisibleto

我在CLR属性上使用WPF的双向绑定,该属性实现了INotifyPropertyChanged。 该属性的setinternal,而getpublic

不幸的是,我收到以下错误:

  

System.Windows.Markup.XamlParseException未处理   消息:类型' System.Windows.Markup.XamlParseException'的未处理异常发生在PresentationFramework.dll中   附加信息:TwoWay或OneWayToSource绑定无法在只读属性' Name'类型' MyType'。

这是预期的行为吗?我本以为内部制定者应该工作得很好...... 请注意,CLR类型在另一个程序集中定义,并且在当前程序集中可见,并具有[assembly: InternalsVisibleTo("MyAssembly")]属性。

有没有人有解决方法/建议?声明程序集是一个类库,因此我无法将set更改为public

3 个答案:

答案 0 :(得分:0)

哦,我的......我刚刚发现,WPF绑定不适用于内部属性。哦,微软......你在想什么?

<强>更新

这是我迄今为止所理解的(谢谢你,@ Grx70):

  • WPF不是.NET框架的本机部分,它只是一个&#34;插件&#34;恰好也是由Microsoft编写的框架。这就是为什么它无法访问程序集的internal成员。
  • 微软本可以允许WPF尊重[assembly: InternalsVisibleTo("XXX")]属性,但截至目前,WPF忽略了它 - 遗憾的是,它没有任何简单的解决方法。 注意:我使用InternalVisibleTo进行了测试 - 包括Signed和Unsigned,以及PresentationFramework,PresentationCore和一大堆其他没有运气的DLL。
  • 我现在能想到的唯一解决方法是创建一个&#34;代理&#34;可以将所有必需成员公开为public的类。这是一个非常PITA(我有很多课程,我讨厌创建相同数量的&#34;代理&#34;类的维护噩梦) - 所以我可能会考虑使用PostSharp,或者Fody或者一些一种织布工自动创建这些&#34;代理&#34;我可以上课。

面对这个问题的任何人都是最好的。

答案 1 :(得分:0)

您可以创建自己的新公共包装器属性,并使用它的getter和setter与您的内部属性进行交互

         internal string _SideTabHeader;

            public string SideTabHeader
            {
                get { return _SideTabHeader; }
                set 
{
    if( value<0)
    {
        do nothing
    }
    else
    {
       _SideTabHeader=value;
    };
}
        }

答案 2 :(得分:0)

这很晚了,还没有解决最初的问题,但是由于它非常相关,可以帮助其他人解决类似的问题...

如果您的内部媒体资源类型为枚举,否则跳过

就我而言,我试图将WPF xaml绑定到从WCF服务继承的类型的属性。解决该简单情况的简单方法是使用int。

public Dictionary<int, string> ProductsList => EnumExtensions.ProductsList;

public int ProductType
{
    get { return (int)_DeliveryProduct.ProductType; }
    set
    {
        if (value.Equals(ProductType)) return;
        _DeliveryProduct.ProductType = (ProductEnum)value;
        RaisePropertyChanged(() => ProductType);
    }
}

_DeliveryProduct 是我对域对象的引用,其属性 ProductType 是一个枚举,但在我的视图模型中,该属性是 int 。 ...请注意, ProductEnum 是从API自动生成的,不能更改为public。

internal static Dictionary<int, string> ProductsList => new Dictionary<int, string>
{
    {(int)ProductEnum.Regular, ProductEnum.Regular.GetDisplayName()},
    {(int)ProductEnum.Intermediate, ProductEnum.Intermediate.GetDisplayName()},
    {(int)ProductEnum.Super, ProductEnum.Super.GetDisplayName()},
    {(int)ProductEnum.Diesel, ProductEnum.Diesel.GetDisplayName()}
};