Binding to an internal property? - c#

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

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 part of your answer in your question itself in the quote from Microsoft:
The properties you use as binding source properties for a binding must
be public properties of your class.
Presumably / speculatively, the reason for this is that internals can only be accessed within the same assembly and not from outside. Binding to internals doesn't work because binding is resolved by the WPF binding engine which is in a separate assembly PresentationFramework.dll.

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.

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.

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!

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.

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.

It is not possible to bind to internal properties. You can make your class as internal though, if you do not want your class to be accessible outside the project.

Related

When should I use property in C# Interface?

I'm new to C# interfaces, I know that inside Interfaces we can put some property like
int speed{ get; set; }
but things is that, the reason property exists is to achieve encapsulation, which provides access to private members, however in interfaces everything is public. Then does it make sense to use property in Interfaces? Or it's just because interfaces are "contracts" so this is sort of normal?
You can use properties in interfaces as public members that are part of your “contract”
A property is a member that provides a flexible mechanism to read, write, or compute the value of a private field c# programming guide
So the backing field is private but the property is public. Therefore it can form part of the interface.
You don't have to use properties. You can use methods too, like this:
public int GetSpeed();
public void SetSpeed(int n);
However, people seem to prefer using a property, and its get and set methods, because it is easier to read and use, and it encapsulates the getter and setter in one place.

Is it possible to view members other than public properties in a PropertyGrid?

Is it possible to view members other than public properties in a PropertyGrid? The documentation says "all public properties of the SelectedObject will be displayed in the PropertyGrid by default". The "by default" seems to imply that it may be possible to view e.g. fields or non-public properties after some configuration.
Please note that I do not actually want to display anything other than public properties, I just need to know what it supports.
So basically you want control over what is displayed inside a property grid. Yes that is possible.
An object may provide custom information about itself by implementing an interface ICustomTypeDescriptor. If this is not implemented, the static TypeDescriptor is used by the property grid.
So we need to implement ICustomTypeDescriptor.
The property information will be returned by the interface method GetProperties(). This method returns an object of type PropertyDescriptorCollection.
Edit: You should take a look at PropertyGrid.BrowsableAttributes for a simpler solution. Programatically Hide Field in PropertyGrid
Some useful links -
.NET Matters: ICustomTypeDescriptor, Part 1
http://www.codeproject.com/Articles/4448/Customized-display-of-collection-data-in-a-Propert

How to override a dependency properties in a generic class?

So I have a class; lets use the ScrollViewer class as an example. It has a dependency property called Content which accepts anything of type System.Object, great!
Let's say I derive a class from ScrollViewer, lets call it ZoomScrollViewer, it adds some basic zooming and panning using the mouse with a keyboard press. It also adds a dependency property of it's own, AutoscaleContent.
Now, I want to be able to put a ZoomScrollViewer into a UI window, but I only want it to accept a Canvas as it's content. Naturally, I go about creating a ZoomScrollViewer<T> class.
However, how can I change the Content property so that only accepts elements of type <T>? Can I override the dependency property? I got a little confused and tried:
public new T Content
{
get { return (T)base.Content; }
set { base.Content = value; }
}
But of course this makes it no longer a dependency property, so all the XAML code fails when I set up the bindings.
Edit: It should also be noted that I've taken a look at using:
ZoomScrollViewer.ContentProperty.OverrideMetadata(typeof(ZoomScrollControl2<T>), new PropertyMetadata(...?));
To see if I could do anything using that, but it seems you can only override the default value, unless I'm missing something?
Update: I've now tried using the following:
public class ZoomScrollControl2<T> : ZoomScrollViewer where T : FrameworkElement
{
static ZoomScrollControl2()
{
ContentProperty.OverrideMetadata(typeof(ZoomScrollControl2<T>), new FrameworkPropertyMetadata(typeof(ZoomScrollControl2<T>)));
}
}
public class CanvasZoomControl : ZoomScrollControl2<Canvas>
{
}
Which I thought would work, but it still seems to accept a Content of any type.
Update: In short I'm not sure if what I want to do is even possible, so I've marked the discussion as the answer, even though it isn't an answer per-se.
I suggest to try that approach as it suggested by this MSDN article.
It should override the referal type, so you can refer to it using derived type.
Dependency Property visibility is not made esplicit in .NET Framework for derived types, as searching right property among the types tree has a cost in terms of performance, and considering that we use DP on UI binding, it can lead to non desirable performance issues.

Difference between Attached and non-Attached Dependency Properties in Silverlight

Okay Stackers, I've spent a good couple of hours on this question, and I want to know if anybody has a definitive answer.
For all the research I've done, I can't find ANY difference between .Register and .RegisterAttached in Silverlight. Now, before you jump the gun and tell me that .RegisterAttached is used for attaching a DP to another class, try implementing an Attached Dependency Property using DependencyProperty.Register(). I have found not a single difference, and so I am at a loss as to what the difference is.
Furthermore, in my specific case, I'm attempting to extend the functionality of the Grid class, and want to give it some extra properties. As such, I've tried listing passing both typeof(Grid) and typeof(FluidLayoutManager) (the implementing class) as the ownerType parameter and it also seems to make very little difference... (I believe it does make a difference when I pass two custom classes from the same namespace. However when passing a Microsoft defined class vs. a custom class, I always have it showing up in the XAML as a DP of the custom class.)
Any clarification on this topic would be much appreciated, as I'm sitting here scratching my head, and wondering if there is any difference at all, or if Microsoft is just screwing with me once again.
Given the discussions flowing in comments I will try to do this one in plain English:
The main difference between Attached Dependency Properties and Dependency Properties (and therefore between .Register and .RegisterAttached) is that RegisterAttached allows the value to be assigned to any dependency object whereas Register only allows it to be attached to the class passed as the ownerType parameter.
As Haris Hasan mentions (deep in the comment thread), your example is using the only type allowed (i.e. CustomControl) and does not show you that the Attached version can be assigned to ANY dependency object.
e.g. you can do this with your Attached Dependency Property (but not a plain DP):
<Grid local:AttacherClass.ADP1="1" x:Name="LayoutRoot" Background="White">
</Grid>
The best reference for ADPs I can find is this one: http://msdn.microsoft.com/en-us/library/ms749011.aspx
We used ADPs as the basis of a localisation system, so that translations could be parasited onto objects during load rather than using horrendously long bindings. Couldn't do that with DPs
Update:
I would also like to clarify that the parent limitation applies to XAML based use of the attribute. From code the parent limitation apparently does not apply.
It is wrong to believe that "RegisterAttached allows the value to be assigned to any dependency object whereas Register only allows it to be attached to the class passed as the ownerType parameter". Here is a perfectly working example of an attached property registered with Register:
class FooPropertyDeclaringType
{
public static readonly DependencyProperty FooProperty =
DependencyProperty.Register("Foo", typeof(int), typeof(FooPropertyDeclaringType));
}
class SomeUnrelatedType : DependencyObject { }
class Program
{
static void Main()
{
var obj = new SomeUnrelatedType();
obj.SetValue(FooPropertyDeclaringType.FooProperty, 10);
Debug.Assert(10 == (int)obj.GetValue(FooPropertyDeclaringType.FooProperty));
}
}
Reflector shows that the only difference between Register and RegisterAttached is that the Register throws out much of the supplied metadata and only preserves it for the instances of registering class (via OverrideMetadata). It means that attributes such as Inherits and various update notifications usually specified in the metadata do not work on properties registered with Register and attached to objects of other types (other than the registering type). So Register is actually a stripped down version of RegisterAttached. It was probably made this way for performance reasons.
In the example linked by Haris Hasan in the comments to his answer, if you change RegisterAttached to Register, the buttons stop moving (because the property no longer provides AffectsParentArrange metadata for Button type) but they are nevertheless redrawn in their new locations when you resize the window. But if you add the same metadata to the Button type after a call to InitializeComponent():
RadialPanel.AngleProperty.OverrideMetadata(
typeof(Button),
new FrameworkPropertyMetadata(
0.0, FrameworkPropertyMetadataOptions.AffectsParentArrange));
then everything works again as if RegisterAttached was called.
They might not be much different as far as implementation is concerned but they are difference in actions i.e. they are different in what they do and are used for.
Simple Register is used for simple dependency properties which you usually are used for bindings and validations so they are normal CLR properties with some additional magic which helps in WPF
RegisterAttached is normally used where you want to expose a property that can be accessed and set in the child class like DockPanel where children of control tells parent where they want to be placed using Dock.Left or Dock.Right. So they are kind of special dependency properties which can be accessed in the child controls (which is not the case with simple Register properties) and they(in case of DockPanel) helps parent control in displaying children
In short one cay say Register is used registering dependency properties which are used in same class while RegisterAttached is used for registering special dependency properties called attached properties and they are used and accessed by classes other than one which defined it
This is a good explanation of Attached Properties and what cannot be achieved through simple DP
If you register with RegisterAttached, it becomes global as a property in the store of any DependencyObject, i.e. you could SetValue on any Dependency Object
If you use Register when Get/Setvalue are called there will be a check that the call is prom an object that is castable to the registering type.
An Example of a property that behaves like RegisterAttached is Grid.Row and Grid.Column.
So exactly what is 'ownerType' used for in RegisterAttached? This issue has been nagging at me for a few years, so I finally took a closer look at 4.6.1 code in WindowsBase.
For any DependencyProperty, attached or otherwise, what it eventually comes down to is what type of PropertyDescriptor WPF obtains for late-bound XAML access, and this isn't determined until the first time (on a per type/property pairing basis) such access is attempted. This deferral is necessary because PropertyDescriptor encapsulates a property bound to a specific type, whereas the point of attached properties is to avoid exactly this.
By the time XAML access occurs, the Register(...) versus RegisterAttached(...) distinction has been lost to the mists of (run)time. As others have noted on this page, 'DependencyProperty' itself doesn't encode a distinction between an attached vs. non- variety. Every DP is assumed to be eligible for either usage, subject only to what can be figured out at runtime.
For example, the .NET code below seems to rely on not finding a matching instance property on the 'tOwner' type as the first requirement for allowing attached access. To confirm this diagnosis, it then checks whether 'tOwner' exposes one of the static access methods. This is a vague check insofar as it doesn't verify the method signatures. Those signatures only matter for XAML access; all actual runtime targets for the attached property must be DependencyObjects, which WPF accesses through DependencyObject.GetValue/SetValue whenever possible. (The VS Designer reportedly does use the static accessors, and your XAML won't compile without them)
The relevant .NET code is the static function DependencyPropertyDescriptor.FromProperty, shown here with my own comments (summary below):
internal static DependencyPropertyDescriptor FromProperty(DependencyProperty dp, Type tOwner, Type tTarget, bool _)
{
/// 1. 'tOwner' must define a true CLR property, as obtained via reflection,
/// in order to obtain a normal (i.e. non-attached) DependencyProperty
if (tOwner.GetProperty(dp.Name) != null)
{
DependencyPropertyDescriptor dpd;
var dict = descriptor_cache;
lock (dict)
if (dict.TryGetValue(dp, out dpd))
return dpd;
dpd = new DependencyPropertyDescriptor(null, dp.Name, tTarget, dp, false);
lock (dict)
dict[dp] = dpd;
/// 2. Exiting here means that, if instance properties are defined on tOwner,
/// you will *never* get the attached property descriptor. Furthermore,
/// static Get/Set accessors, if any, will be ignored in favor of those instance
/// accessors, even when calling 'RegisterAttached'
return dpd;
}
/// 3. To obtain an attached DependencyProperty, 'tOwner' must define a public,
/// static 'get' or 'set' accessor (or both).
if ((tOwner.GetMethod("Get" + dp.Name) == null) && (tOwner.GetMethod("Set" + dp.Name) == null))
return null;
/// 4. If we are able to get a descriptor for the attached property, it is a
/// DependencyObjectPropertyDescriptor. This type and DependencyPropertyDescriptor
/// both derive directly from ComponentModel.PropertyDescriptor so they share
/// no 'is-a' relation.
var dopd = DependencyObjectProvider.GetAttachedPropertyDescriptor(dp, tTarget);
/// 5. Note: If the this line returns null, FromProperty isn't called below (new C# syntax)
/// 6. FromProperty() uses the distinction between descriptor types mentioned in (4.)
/// to configure 'IsAttached' on the returned DependencyProperty, so success here is
/// the only way attached property operations can succeed.
return dopd?.FromProperty(dopd);
}
Summary: When calling RegisterAttached to create an attached DependencyProperty, the only thing 'ownerType' is used for is to identify a type which defines appropriate static Get/Set accessors. At least one of those accessors must exist on 'ownerType' or XAML attached access will not compile or silently fail. Although RegisterAttached does not fail in this case, and instead successfully returns a defunct DP. For DPs intended for attached use only, 'tOwner' doesn't have to derive from DependencyObject. You can use any regular .NET class, static or non-static, and in fact can even be a struct!

When should we use private variables and when should we use properties. Do Backing Fields should be used in same class?

In most of the cases we usually creates a private variable and its corresponding public properties and uses them for performing our functionalities.
Everyone has different approach like some people uses properties every where and some uses private variables within a same class as they are private and opens it to be used by external environment by using properties.
Suppose I takes a scenario say insertion in a database.
I creates some parameters that need to be initialized.
I creates 10 private variables and their corresp public properties
which are given as
private string name;
public string Name
{
get{return name;}
set{name=value;}
}
and so on. In these cases mentioned above, what should be used internal variables or properties.
And in those cases like
public string Name
{
get{return name;}
set{name=value>5?5:0;} //or any action can be done. this is just an eg.
}
In such cases what should be done.
What is the conclusion
I actually meant to ask this.
Should we use variables within that class or not or should we use properties everywhere within same class as well.
If you use auto-implemented properties, then the field will be hidden, so you are forced to use the property, even in the class where the property is defined. Auto-implemented properties are a good idea, unless you need to add some logic to the getter/setter.
If the only use for the private variable is as a storage container, you might use:
public string Name {get; set;}
IMHO one should never make variables public - always use properties so you can add constraints or change behaviours later on whitout changing the interface.
Made things more readable:
I expose my data always through properties.
If I do not need additional logic (e.g. validation) I use implicit properties. This way there is no backing field and I cannot access it by accident. If I need to add some additional logic I can easily change the implicit property to a "traditional" one. As I use the property everywhere I do not have to worry that my extra logic is not called.
If I need something extra (like validation) then I have a private backing field, but I access this field only in the property body (get/set accessors). Again I do not need to worry if I change something in the property: My code will always use the same logic.
The only reason for not calling the property in my opinion would be if for some reason I really do not want any additional logic to be called, but this seems a dangerous thing so I rather avoid it...
I never expose public variables. Why? Because I can't lay constraints on them, whereas I can when I'm using properties. I can first check the value if it meets my constraints (e.g. an email address) and then I save it. Otherwise I throw an Exception.
You should never expose public variables without a very good reason. It is tough to say never, because if you trying to interop with comm type components you might be required too.
Anything publicly exposed should be a property. Why is that?
The reason is if you need to change the source of the value, or add some business logic checking if it is a public member you are going to require anything using the code to change. If it is a property you can change the internal logic and not require anybody using it to change the code.
I personally use properties and only create members variables when I want a property to do more than getting or setting (since this is easy with C# 3.0 with shortcut properties).
If I want to keep a property from being publicly exposed I make it as private, and only expose it when I have too.
We require explicit private variables in some situation like validation before set.Sometime we also need to conversion of input, for instance , formatting the input.

Categories

Resources