0

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

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

System.Windows.Markup.XamlParseException 未处理消息:PresentationFramework.dll 中发生“System.Windows.Markup.XamlParseException”类型的未处理异常附加信息:TwoWay 或 OneWayToSource 绑定无法在只读属性“名称”上工作输入“我的类型”。

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

有没有人有解决方法/建议?声明程序集是一个类库,因此我不能将其更改setpublic.

4

3 回答 3

0

这已经很晚了,并没有解决最初的问题,但由于非常相关,它可能会帮助其他人遇到非常相似的问题......

如果您的内部属性是 Enum 类型,则跳过

在我的情况下,我试图将 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 自动生成的,不能更改为公共的。

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()}
};
于 2020-11-07T03:50:10.953 回答
0

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


更新:

这是我到目前为止所理解的(谢谢@Grx70):

  • WPF 不是 .NET 框架的本机部分,它只是一个“插件”框架,恰好也是由 Microsoft 编写的。这就是它无法访问internal您的程序集成员的原因。
  • 微软本可以允许 WPF 尊重该[assembly: InternalsVisibleTo("XXX")]属性,但截至目前,WPF 忽略了它 - 不幸的是,这并没有留下任何简单的解决方法。 注意:我使用InternalVisibleToPresentationFramework、PresentationCore 和一大堆其他 DLL 测试了 - 有符号和无符号,但没有运气。
  • 我现在能想到的唯一解决方法是创建一个“代理”类,它可以将所有必需的成员公开。这是一个相当大的 PITA(我有很多类,我讨厌创建相同数量的“代理”类带来的维护噩梦) - 所以我可能会考虑使用 PostSharp、Fody 或某种织布机来自动- 如果可以的话,创建这些“代理”类。

祝其他面临这个问题的人一切顺利。

于 2016-11-13T08:19:42.553 回答
0

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

         internal string _SideTabHeader;

            public string SideTabHeader
            {
                get { return _SideTabHeader; }
                set 
{
    if( value<0)
    {
        do nothing
    }
    else
    {
       _SideTabHeader=value;
    };
}
        }
于 2016-11-13T09:56:30.500 回答