Binding controls to class properties - is this technically possible? - c#

I have yet to find a "nice" way to do two way databinding in .Net.
The one thing I don't like for example in the present asp.net two way databinding is doing the binding in the aspx page is no compile time checking, ie:
<asp:TextBox ID="TitleTextBox"
runat="server" Text='<%# Bind("Title_oops_spelled_wrong") %>'>
I would like to have something like this:
Class Binder
Public Sub BindControl(ctl As Control, objectProperty As ???????)
'// Add ctl and objectProperty to a collection
End Sub
What I don't know is possible is, how to receive the objectProperty in my example; I want to receive a reference (ie: a pointer) to the property, so later, via this reference, I can either read from or write to the property.
Can this somehow be done with delegates perhaps??
UPDATE:
Note, I want to add the control reference to a binding collection, this collection would then be used for binding and unbinding.

Is there a reason that you want to avoid using the .NET data binding mechanism? It handles keeping parity between the control's value and the class's property value already, and provides rich design-time support.
You can interface with the data binding engine in two ways: either programatically or through the designer. To do basic data binding programatically is trivial. Say I have a class named "FooClass" with a string property named "MyString". I have a TextBox named myTxtBox on a form with an instance of FooClass called foo and I want to bind it to the MyString property:
myTxtBox.DataBindings.Add("Text", foo, "MyString");
Executing this will cause updates to the TextBox to get assigned to the property, and changes to the property from elsewhere will be reflected in the TextBox.
For more complex data binding scenarios, you'll probably want to create an Object Data Source in your project and put a BindingSource on your form. If you need help with specific steps in creating the data source I can help, but in general you'll create the source in your project and select the class to which you want to bind. You can then place a BindingSource on your form, point it at your object project data source, then use the Visual Studio designer to bind properties for your controls to properties on your object. You then set the DataSource property in your code to an instance of the class or collection to which you want to bind.
As a side note, as far as I am aware there is no "property delegate", as properties are actually function pairs (a get_ and a set_).
UPDATE:
As I read your comments, I'd like to point out that .NET data binding, even at the control level, does NOT automatically use reflection. Data binding is built around type descriptors and property descriptors, both for the bound control and the data source. It's true that if one or both of these sides does not implement specific property and type description then reflection will be used, but either side is more than free to provide its own description profile which would NOT use reflection.

The Bind is not a method and there is no some object behind the scene holding binding relationship. It's just a "magic" word that page parser uses to generate code behind. Essentially, it translates into Eval and control building code. The Eval, on the other hand, will use reflection to access bound item's properties.
If I understand correctly what you want, read-only property binding already works. Assuming you have a property Title in your class:
<asp:TextBox ID="TitleTextBox" runat="server" Text='<%# Title %>' />
For two-way binding, you'd have to either create your own Template or reflect existing one and pass the ExtractTemplateValuesMethod method and assign the DataBinding event to your control. This is where .NET uses Eval, which you'd replace with the property assignment.
In my opinion, that is what the DataBinding event is for.
However, if you question is more about whether one can have a reference to a property, then I'm afraid not. There is no property per say. You have to methods (get and set) and an entry in the metadata. You could store a reference to the object and property name, but then you'd have to use reflection.
You could use the delegates, but that would take you back to the same code as the one .NET generates, which is defining ExtractTemplateValuesMethod and doing DataBinding anyhow.

One solution would be to pass objectProperty ByRef.
If you want compile time type checking you would need to overload BindControl for any types that you plan on using. For example:
Public Sub BindControl(ctl As ITextControl, ByRef objectProperty As String)
objectProperty = ITextControl.Text
End Sub
Public Sub BindControl(ctl As ITextControl, ByRef objectProperty As Integer)
Integer.TryParse(TextControl.Text, objectProperty)
End Sub
..

Related

When should I use dependency properties in WPF?

When should I use dependency properties in WPF?
They are static, so we save a lot on memory, compared to using .NET properties.
Other gains of using dependency properties over .NET properties are:
1) no need to check thread access
2) prompt a containing element to be rendered
etc...
So it seems I should ALWAYS use dependency properties in my projects where I use WPF?
Maybe for some trivial properties of helper classes here and there I could
get away with .NET properties...
Dependency Property is a broad concept to explain which might take couple of pages to write. So just to answer your main question, Dependency property is used where
You know the property is going to be the binding target i.e you are creating a user control/custom control and want property that should be binding driven.
You want automatic property change notifications (coerse and validation also).
We want value inheritance in styles,themes, parent or default value.
There is not need to create the properties on Model or ViewModel layer as dependency properties most of the time as that is not going to help much on memory saving front as most of the properties we define in model/VM will have values per instance as they will be constantly changing. Resolving Dependency property value is a burden in itself so making property dependency unnecessarily is not advisable.
Thanks
The main reason to create DependencyProperty is when you write you own WPF control.
DependencyProperties can be used as binding source and target, and can be animated.
The properties of all framework's controls are implemented as DependencyProperty, that why you can make powerful data binding in XAML.
However in most situation, like in with the MVVM pattern, you don't need dependency properties, INotifyPropertyChanged is enough.
The main difference is, that the value of a normal .NET property is read directly from a private member in your class, whereas the value of a DependencyProperty is resolved dynamically when calling the GetValue() method that is inherited from DependencyObject.
When you set a value of a dependency property it is not stored in a field of your object, but in a dictionary of keys and values provided by the base class DependencyObject. The key of an entry is the name of the property and the value is the value you want to set.
The advantages of dependency properties are
Reduced memory footprint:
It's a huge dissipation to store a field for each property when you think that over 90% of the properties of a UI control typically stay at its initial values. Dependency properties solve these problems by only store modified properties in the instance. The default values are stored once within the dependency property.
Value inheritance:
When you access a dependency property the value is resolved by using a value resolution strategy. If no local value is set, the dependency property navigates up the logical tree until it finds a value. When you set the FontSize on the root element it applies to all textblocks below except you override the value.
Change notification:
Dependency properties have a built-in change notification mechanism. By registering a callback in the property metadata you get notified, when the value of the property has been changed. This is also used by the databinding.
check the below url for more details about the magic behid it
dependency properties in WPF
CLR Property vs. Dependency Property
A CLR property reads directly from the private member of the class. The Get() and Set() methods of the class retrieve and store the values of the property.
Whereas when you set a value of a Dependency Property it is not stored in a field of your object, but in a dictionary of keys and values provided by the base class DependencyObject. The key of an entry is the name of the property and the value is the value you want to set.
Advantages of a Dependency Property
Less memory consumption
The Dependency Property stores the property only when it is altered or modified. Hence a huge amount of memory for fields are free.
Property value inheritance
It means that if no value is set for the property then it will return to the inheritance tree up to where it gets the value.
Change notification and Data Bindings
Whenever a property changes its value it provides notification in the Dependency Property using INotifyPropertyChange and also helps in data binding.
Participation in animation, styles and templates
A Dependency Property can animate, set styles using style setters and even provide templates for the control.
CallBacks
Whenever a property is changed you can have a callback invoked.
Resources
You can define a Resource for the definition of a Dependency Property in XAML.
Overriding Metadata
You can define certain behaviours of a Dependency Property using PropertyMetaData. Thus, overriding a metadata from a derived property will not require you to redefine or re-implement the entire property definition.
Perhaps you should take another look at the Dependency Properties Overview page at MSDN.
Personally, I would only ever create a DependencyProperty when I really need to. For the most part, I use normal CLR properties in data type and view model classes to bind to... this is absolutely fine, as long as I implement the INotifyPropertyChanged interface.
So for all of my usual data bindings, I use normal CLR properties. I only declare a Dependency Property in order to provide some added functionality in a UserControl.
Dependency properties are used when you want data binding in a UserControl, and is the standard method of data binding for the WPF Framework controls. DPs have slightly better binding performance, and everything is provided to you when inside a UserControl to implement them.
Otherwise, you typically use INotifyPropertyChanged for binding elsewhere, since it's easier to implement in stand-alone classes and has less overhead. As far as your original assumptions:
There is a local instance of your variable, you definitely do not save any overhead over a property since there is significant data binding logic built-in.
They must be accessed on the main thread.

WPF UserControl pre-configuration

I'm designing an user control and I'd like to make its behaviour configurable - but just once, when it's created. I don't need it to adapt later on, since I know beforehand that a specific window will to use it with a specific configuration.
Consider this simple markup:
<MyControl SomeProperty="True" SomeOtherProperty="12345" />
SomeProperty and SomeOtherProperty are DependencyProperties declared in my codebehind.
The issue is: The control does some preprocessing of its input data in its constructor, before InitializeComponent() is called. On that stage, I don't have the access to SomeProperty or SomeOtherProperty defined by the user - they still have the default values.
After that, if these properties are set in the XAML, they're assigned the values after the constructor. I can respond to them by introducing a PropertyChangedCallback and performing the calculations over again after each property is updated.
This is sub-optimal since I just want to pass the values once and make sure that the control's initialization logic is only ran once too - already with correct settings. The solution with PropertyChangedCallbacks requires me to make this control more complex, i.e. responsive to any changes to these dependency properties during the control's whole lifetime. This is much more than I need - it would be satisfactory for my properties to be read-only and set only once at the moment of control creation.
How can I manage to do that while keeping the XAML markup clean?
Your control must be constructed in order for WPF to set the properties - there is no way to "delay" the construction until after the properties are set.
Instead of putting your initialization logic in the constructor, you might want to try putting it elsewhere, such as subscribing to the Loaded event and initializing there. This will happen after the properties are set.

Need a short and clear definition for "Dependency Properties"

I'm trying to figure out what exactly Dependency Properties are, but when I look anywhere for a definition, I only find "how to use" but not "what it is".
Imagine you are asked on a job interview - what is a dependency property. What would be your answer?
A DependencyProperty is a property whose value depends (or can depend) on some other source (such as animation, data binding, styles, or visual tree inheritance). A regular property's value is stored in the object it belongs to, while you can think of a dependency property as being stored in a database somewhere. This database is essentially composed of a dictionary that maps (object, property) pairs to their values, along with a mapping of which properties depend on other properties (e.g. so when you change the DataContext of a Panel, it can notify all the children inside the panel).
So why do they store property values in some magic database somewhere? There are a few reasons:
It reduces storage space. Adding a property (even if its value is null) to a class adds 4 bytes (8 for a 64-bit process) of space to every instance of the class. A DependencyProperty only takes up space when an instance has a value. For example, a FrameworkElement has dozens of dependency properties, most of which are never assigned values. If all those properties were stored in the class, each instance would be hundreds of bytes. Instead each instance is only about 40 bytes.
It enables attached properties. Properties like Canvas.Left and Grid.Row have to be stored on objects that have never heard of a Canvas or Grid, so where do you put them? You put them in a database somewhere.
It enables automatic property changes. Imagine how you would implement something like styles or property inheritance (the ability to set something like a font or data context on a parent element and have its value propagate to all child elements). Having all of this stored in a database makes it so the code is all in one place instead of being implemented separately for each object and property that needs it.
"gives you a bunch of infrastructure to do all the things that you often want to do with a normal property - validate it, coerce it into a proper range, give out change notifications, and a number of other aspects."
WPF Tutorial - Introduction To Dependency Properties
A dependency property is a property that is backed by the WPF property system instead of by a field in the declaring class.
The significance of this is that, because WPF owns the property, WPF can factor in various considerations when calculating the property value -- such as animations, styles and data bindings. Another consequence is that because properties are managed by WPF they don't have to be declared on the classes that conceptually have the state: hence, atttached properties, which allow e.g. a Grid to associate Grid-specific state with non-Grid objects.
(By the way, I've mentioned WPF above because this is the main framework that uses DPs, but Windows Workflow Foundation also has the notion of dependency properties. So to be strictly correct a DP is a property that is backed by an external property system, specifically one which allows factors other than "the last set value" to come into play when getting the property value.)
MSDN provides a good definition, description and examples
For more deep understanding of DependencyProperty check here
A dependency property depends on multiple providers for determining its value at any point in time. These providers could be an animation continuously changing its value, a parent element whose property value propagates down to its children, and so on.
Arguably the biggest feature of a dependency property is its built-in ability to provide change notification.
Whenever the value of a dependency property changes, WPF can automatically trigger a number of actions, depending on the property’s metadata. These actions can be re-render-
ing the appropriate elements, updating the current layout, refreshing data bindings, and
much more. One of the most interesting features enabled by this built-in change notifica-
tion is property triggers, which enable you to perform your own custom actions when a
property value changes, without writing any procedural code

WPF - Dynamic tooltip

I have a class ToolTipProvider
which has a method
string GetToolTip(UIElement element)
which will return a specific tooltip for the UIElement specified, based on various factors including properties of the UIElement itself and also looking up into documentation which can be changed dynamically. It will also probably run in a thread so when the form first fires up the tooltips will be something like the visual studio 'Document cache is still being constructed', then populated in the background.
I want to allow this to be used in any wpf form with the minimum effort for the developer. Essentially I want to insert an ObjectDataProvider resource into the Window.Resources to wrap my ToolTipProvider object, then I think I need to create a tooltip (called e.g. MyToolTipProvider) in the resources which references that ObjectDataProvider, then on any element which requires this tooltip functionality it would just be a case of ToolTip="{StaticResource MyToolTipProvider}"
however I can't work out a) how to bind the actual elemnt itself to the MethodParameters of the objectdataprovider, or b) how to force it to call the method each time the tooltip is opened.
Any ideas/pointers on the general pattern I need? Not looking for complete solution, just any ideas from those more experienced
Create a new user control which functions as a tool-tip view factory.
Use your control as the tool-tip, passing any data you need for the factory to your control using binding (e.g. the data, the containing control, ...)
<AnyControl>
<AnyControl.ToolTip>
<YourToolTipControl Content="{Binding}" />
</AnyControl.ToolTip>
</AnyControl>
Not calling myself an expert, but I'd probably attempt such a feature with an attached property. This would be attachable to any element in your UI and you can specify an event handler that gets access to the object to which the property is being attached as well as the value passed to the attached property. You can keep a reference to the element to which your attached property was attached and you would then be able to change the ToolTip whenever you want.

What is the use of Tag property in Tree view control C#?

What is the use of Tag property in Tree view control C#?
How can we work with it?
A common use for the Tag property is to store data that is closely associated with the control (from MSDN). Any type derived from the Object class can be assigned to this property.
It's a cheap way of avoiding inheritance to add just one Property.
Every control that inherits from Control in winform has a Tag property where you can store metadata for later use, for example you can store database id in that property for every item and load data from database on tree node click
As ArsenMkrt said, every control that inherits from Windows.Forms.Control has the Tag property. This is of type System.Object, so you can store anything you want.
The idea of the Tag property probably comes from VB6, which also has this, but in VB6 it is limited to String values.
When writing a UI, sooner or later you will find yourself handing an event in which you know the UI control that the event came from, but you also need to know what backing data that control is associated with. Usually, that problem can be solved with data binding, but not always. In the latter case, you can manually populate the Tag property with whatever you need to make the code work.

Categories