【问题标题】:Binding to an internal property?绑定到内部属性?
【发布时间】:2025-12-16 22:20:03
【问题描述】:

我正在尝试使用 MVVM 做一些不同的事情。在我们的 ViewModel 中,绑定到 View 的属性是公开的。我以按钮绑定为例。这是一个简单的示例。

View.xaml:

<Button Content="Test Button" Command="{Binding TestButtonCommand}" />

ViewModel.cs

private ICommand _testButtonCommand;
public ICommand TestButtonCommand
{
    get { return _testButtonCommand?? (_testButtonCommand= new RelayCommand(SomeMethod)); }
}

我的问题是我们可以将TestButtonCommand 设为内部而不是公开吗?内部意味着当前项目可以访问它,所以他们这样做应该没有问题吗?但是当我试图这样做时,它没有奏效。在 getter 中添加断点未命中。那么为什么我们不能让它内部化呢?

这是来自 msdn 的链接。

http://msdn.microsoft.com/en-us/library/ms743643.aspx

您用作绑定源属性的属性必须 成为您班级的公共财产。明确定义的接口 不能出于绑定目的访问属性,也不能受保护, 没有基础的私有、内部或虚拟属性 实施。

为什么我们不能这样做?

如果在同一个项目中工作,访问 internal 与 public 相同。那为什么我们不能在这里使用 internal 呢?这些应该公开肯定是有原因的,我正在寻找这个原因。

internal ICommand TestButtonCommand { ...... }

【问题讨论】:

标签: c# wpf mvvm binding


【解决方案1】:

如果在同一工作中访问内部与公共相同 项目。那为什么我们不能在这里使用 internal 。一定是有原因的 这些应该是公开的,我正在寻找这个原因。

在微软的引述中,你的问题本身就有部分答案:

您用作绑定源属性的属性必须 成为你的类的公共属性

大概/推测,原因是内部组件只能在同一个程序集中访问,而不能从外部访问。绑定到内部不起作用,因为绑定由 WPF 绑定引擎解析,该引擎位于单独的程序集 PresentationFramework.dll 中。

【讨论】:

  • 那么,这怎么可能绑定到本身是内部的视图模型类?
  • 天啊,天啊,这让我在 Winforms 中发疯了。显而易见,但并非同时发生。谢谢。
  • 我认为这不是很清楚,但我相信答案是正确的。属性不是公共的这一事实意味着绑定引擎本身无法访问它们,因此它需要公共属性才能起作用。
  • @UuDdLrLrSs:我不明白建议的原因。绑定引擎不是将目标属性名称作为字符串获取吗?至少对于在运行时创建的Binding 对象来说肯定是这种情况。从那个字符串中,它只能通过使用像反射这样的机制来找到实际的属性。但是一旦使用反射,属性是公共的、内部的还是其他任何东西都不再重要——甚至可以通过反射找到和访问私有成员。请您详细说明为什么您认为推理是正确的 - 也许我遗漏了什么?
  • @O.R.Mapper 它似乎不是 .NET 或反射本身的限制,所以我认为这是 WPF 中绑定的有意限制。我不知道微软这样做的理由是什么。这可能是技术限制,也可能是其他原因。我可以推测,如果内部属性可能并非在所有情况下都有效,那么它们可能会选择 public 只是为了保持一致性。
【解决方案2】:

Binding 仅支持公共属性。 MSDN 参考:

http://msdn.microsoft.com/en-us/library/ms743643.aspx

在参考文献中引用

您用作绑定源属性的属性必须 成为您班级的公共财产。明确定义的接口 不能出于绑定目的访问属性,也不能受保护, 没有基础的私有、内部或虚拟属性 实施。

【讨论】:

  • 我试图在这里找到我们不能使用内部的原因。如果我们在同一个项目中工作,则与 public 相同。
【解决方案3】:

internal 可见性实际上只对编译器和 IL 验证器有意义,因为它们知道成员访问的完整上下文; WPF 绑定引擎没有。它知道属性上存在绑定;它不知道是谁设置了该属性。它可以在 XAML 中设置,或者在运行时动态设置(从技术上讲,即使您在 XAML 中设置它,它仍然是动态应用的)。

由于无法强制执行访问规则,因此允许绑定到internal 属性将等同于允许绑定到private 属性,而不是public 属性。

【讨论】:

    【解决方案4】:

    显然,这取决于您在这种情况下要达到的目标 - 您没有说明总体目标是什么。我刚刚在我的代码中遇到了类似的问题,并且也遇到了针对我的案例的解决方案。 我的一个库包含具有各种属性的辅助对象,但是当在应用程序项目中使用这些对象时,我只想查看对我有用的属性 - 我想隐藏,例如 Command 属性。

    我对库的“用户”隐藏它们的解决方案是添加

    <EditorBrowsable(EditorBrowsableState.Never)>
    

    归因于我很少或不感兴趣的每个属性。

    希望对某人有所帮助!

    【讨论】:

      【解决方案5】:

      来自http://msdn.microsoft.com/en-us/library/ms743643.aspx

      对于 CLR 属性,数据绑定与绑定引擎一样工作 能够使用反射访问绑定源属性。 否则,绑定引擎会发出警告,指出该属性 找不到并使用回退值或默认值,如果 它是可用的。

      【讨论】:

        【解决方案6】:

        创建的内部属性破坏了良好的 OO 设计并破坏了封装。 您可以为您的案例使用内部设置访问器(和公共获取访问器)。

        public ICommand SaveCommand
        {
            get;
            internal set;
        }
        

        如果您将一个字段封装到一个属性中,您应该制定一个规则,即始终通过属性访问该字段,即使在您的类中也是如此。这是最好的做法。

        【讨论】:

          【解决方案7】:

          无法绑定到内部属性。不过,如果您不希望在项目之外访问您的课程,您可以将您的课程设为内部课程。

          【讨论】: