Making binding property internal instead of public

2020-02-06 06:28发布

I am trying some different things using MVVM. In our ViewModel properties which are bind to View are public. I am taking example of a button binding. Here is a simple sample.

View.xaml:

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

ViewModel.cs

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

Here my question is that can we make TestButtonCommand internal instead of public? Internal means it is accessible to current project so their should not be any problem doing that? But when I tried to do that it didn't worked. Adding a breakpoint in getter was not hit. So why we cannot make it internal.

Here is the link from msdn.

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

The properties you use as binding source properties for a binding must be public properties of your class. Explicitly defined interface properties cannot be accessed for binding purposes, nor can protected, private, internal, or virtual properties that have no base implementation.

Why we cannot do this? In case of access internal is same as public if working in the same project. Then why we cannot use internal here. There must be a reason that these should be public, and I am looking for that reason.

internal ICommand TestButtonCommand { ...... }

7条回答
Juvenile、少年°
2楼-- · 2020-02-06 06:54

In case of access internal is same as public if working in the same project. Then why we cannot use internal here. There must be a reason that these should be public, and I am looking for that reason.

You have answer in your question only since internals can only be accessed within the same assembly and not from outside. This is the only reason binding to internals doesn't work because binding is resolved by binding engine and not by your assembly and its in separate assembly PresentationFramework.dll to be precise if you are looking for that.

查看更多
爷的心禁止访问
3楼-- · 2020-02-06 06:55

The internal visibility is really only meaningful to the compiler and the IL verifier, because they know the full context of the member access; the WPF binding engine does not. It knows that a binding exists on a property; it has no idea who set the property. It could have been set in the XAML, or dynamically at runtime (technically, even if you set it in the XAML, it is still applied dynamically).

Since there is no way to enforce the access rules, allowing binding to internal properties would be equivalent to allowing binding to private properties, not public properties.

查看更多
虎瘦雄心在
4楼-- · 2020-02-06 07:02

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

For CLR properties, data binding works as long as the binding engine is able to access the binding source property using reflection. Otherwise, the binding engine issues a warning that the property cannot be found and uses the fallback value or the default value, if it is available.

查看更多
淡お忘
5楼-- · 2020-02-06 07:09

Obviously, it depends on what you're trying to achieve from this situation - you don't state what the overall aim is. I have just come across a similar problem with my code, and also happened upon a solution for my case. One of my libraries contains helper objects with various properties, but when these are used in the application project, I only want to see the properties that are of any use to me - I wanted to hide, for example, the Command properties.

My solution to hide them from the 'user' of the library is to add the

<EditorBrowsable(EditorBrowsableState.Never)>

attribute to each property that bears little or no interest to me.

Hope that helps someone!

查看更多
一纸荒年 Trace。
6楼-- · 2020-02-06 07:11

Binding is only supported for public properties. MSDN reference:

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

As quoted in the reference

The properties you use as binding source properties for a binding must be public properties of your class. Explicitly defined interface properties cannot be accessed for binding purposes, nor can protected, private, internal, or virtual properties that have no base implementation.

查看更多
爱情/是我丢掉的垃圾
7楼-- · 2020-02-06 07:19

Created internal property are breaking good OO design and are breaking encapsulation. You can use internal set accessor (and public get accessor) for your case.

public ICommand SaveCommand
{
    get;
    internal set;
}

If you have a field encapsulated into a property, you should make it a rule to always access that field throught a property even inside your class. It's best practise.

查看更多
登录 后发表回答