Dynamic Name to the Control Template in WPF? - c#

We need to assign the Name property at the runtime using the data binding. We have the control template defined and WPF doesn't allow to bind the name from the the Data Bind object.
If I do, I get error like,
Error 3 MarkupExtensions are not
allowed for Uid or Name property
values, so '{Binding Name}' is not
valid. Line 15 Position
36. C:\Users\gsubramani\Workspace\ProLinkIII_Experiment\BasicFrame\Resources\TreeTemplate.xaml 15 36 BasicFrame
To work around, Is it possible to define a custom property which intern set the Name property of the control through data binding?
I don't know how to the handle the DependencyProperty in WPF so that I can define a custom property that intern set the Name property of the control? ( I am very new to WPF world).

If you need this for UI Automation, I'd recommend using the solution described here:
http://www.jonathanantoine.com/2011/11/03/coded-ui-tests-automationid-or-how-to-find-the-chose-one-control/
You can use the AutomationProperties.AutomationId with binding in WPF, and you can use this value as automationid in your UI Automation client.

You would need to define an attached dependency as per the documentation here:
http://msdn.microsoft.com/en-us/library/cc903943%28VS.95%29.aspx
Then provide a method which is invoked when this property changes. You can do this by adding another argument to the propertyMetdata, that points to a static method:
private static void OnMyNamePropertyChanged(DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
// d is the object which the attached property has been set on
}
In this handler, d, is the object that the property has been attached to, and e.NewValue will contain the name.
However, I think it is a little odd that you want to bind the Name of your elements. Can you please share why you want to do this?
Regards, Colin E.

Related

How to control two-way binding initial update direction

Every now and then I face a situation where I need to set a two-way binding on a property where it would be preferred that upon setting the binding the initial update will be performed in target-to-source direction and not source-to-target. That is, when the binding is set the source property value is updated so that it reflects the target property value, which stays unchanged.
Is such scenario possible? And if it is, how can it be accomplished?
Of course there are several workarounds, such as caching the target property value, setting the binding and then restoring the cached value, but I'm interested a direct answer rather than a workaround.
Example
Let's say we have a TextBox with Text property set to "foo". Also, we have a view-model with Name property (of type string) set to null. Now what I want to achieve is to bind the Text property to the Name property while preserving the "foo" value. Important thing here is to avoid setting Text to null and then back to "foo" (for whatever reason, e.g. because clearing the TextBox causes other controls to clear as well).
Then the best practice is 1) to read the existing value from the control (Clearly Xaml is not supposed to have data binding). 2) At "Load" event, the control needs to create and establish data binding by calling "SetBinding." 3) Finally get the binding expression for the control and update source with the value from 1).
All the code should be implemented in "View" code, not in "ViewModel."
e.g.) This code snippet is not tested, but has come from my head in the ball park.
private void Loaded(object sender, RoutedEventArg arg)
{
...
var text = textBox.Text;
var binding = new Binding();
... binding property here
textBox.SetBinding(TextBox.TextProperty, binding);
textBox.Text = text;
var expression = BindingExpression.GetBindingExpression(textBox, TextBox.TextProperty);
expression.UpdateSource();
}
How about creating an Attached Property that can be used to any UIElement? This should address the universality requirement.
<TextBlock Text="foo"
GlobalAttachedProperty:Value="{Binding Path=A_ValueFromVM_OR_SomeWhereElse}"
GlobalAttachedProperty:Property="Text"/>
The Value property just contain a callback to set the binding when there is a change. You can add some fancy routine that do this just once.
Then the Property is just a way to get the actual property for binding purposes. There are some other way to accomplish this but this is the more direct way.
I think that the best option is to set a default value in your model class. This is the purpose of the view model.

Checkbox with both a default content values as well as one from binding

I have a a checkbox in XAML where i need the content to have a default value, lets say: "FooText", but also a binding to a field in an object, that can change.
The idea is that is that at load the checkbox should show the default content, but when an object is loaded the content should change accordingly.
Is this possible, and if so, how? I have some idea that i might be doable in a template, but since im pretty new to WPF i have no idea how to achieve the required result.
Im using the MVVM pattern.
Hope that someone might have a good idea:-D
You could use a default object for that, where you set all properties to the default value you want and then use it as DataContext.
Another thing is the TargetNullValue on Bindings. Using that you can set a default value to show if the target value of a binding is null.
It really depends on what you mean by "default value". WPF Databinding allows for a few ways to handle "default values":
FallbackValue: This allows you to specify a value if there is an issue with the databinding itself. For example, if you are binding to a property that does not exist on the viewmodel (DataContext).
TargetNullValue: This allows you to specify a value if the binding value is null, which is very possible for string values.
You can use both if you want to account for bad binding and null values, it's up to you. Either way, you should use FallbackValue often.
Create a checkboxContent property in viewmodel
set a default value to its private variable _checkboxContent = "FooText";
Bind this property to checkbox Content
When the object loads, assign the object property to checkboxContent property

What's the framework mechanism behind dependency properties?

I have been reading about dependency properties in several books but all have one thing in common, they just tell us how they are implemented( using static readonly DependencyProperty etc.) but does not tell the exact way they work from inside.
I mean they are implemented as static but still applies to all objects.
Second point of confusion is attached properties.
Is there any tutorial available that can explain all these concepts in an easy way?
My mental model of how dependency properties work:
Any DependencyObject class implements two special properties. One, a static property of the class, is a dictionary of DependencyProperty objects. Every instance of the class can look inside that dictionary to find metainformation about each DependencyProperty - the property's name, its type, any callbacks that have to be called when it's get and set, how it participates in property inheritance, and so on. When you register a dependency property, you're adding an entry to this dictionary.
The other property is an instance property: it's a dictionary, keyed by DependencyProperty, that contains the local value of each DependencyProperty, if it has been set.
The SetValue and GetValue methods that you implement in the setter and getter of the CLR property are basically lazy evaluation on steroids. Instead of storing and retrieving the value of the property in a backing field, they store and retrieve the value of the property in the value dictionary.
The magic of dependency properties is in what GetValue and SetValue actually do.
GetValue looks up the value for the property in the object's value dictionary. If it doesn't find it, it calls GetValue on the parent element, to get what the parent element thinks the value is. For instance, when you create a TextBox in a Window, anything that looks at the TextBox's FontFamily is actually calling GetValue. Unless you've explicitly set the font, there's no entry in its dictionary for that property. So GetValue asks the parent element for the value. The parent element may or may not have FontFamily set; if not, its call to GetValue to returns the value from its parent. And so on, until the Window object is reached and the actual FontFamily value is found.
If you set FontFamily on the TextBox, SetValue stores the value in the value dictionary. The next time anything needs to get the value of the FontFamily for that TextBox, GetValue finds the value in the dictionary and returns it, so it doesn't need to ask the parent element.
If you set FontFamily on the Window, SetValue not only updates the value in Window's value dictionary, it fires off a property-change event that everything dependent on the property hears. (That's why they're called dependency properties, remember.) And if the thing depending on the property is itself a dependency property, it fires off its own property-change events. This is how it is that changing the FontFamily on the Window changes the font for every control in the window and also prompts WPF to re-render the controls that have changed.
Attached properties work using the same kind of approach. Any object that can have attached properties has a dictionary that the attached properties' values are stored in. When you set Grid.Column on a CheckBox in XAML, you're just adding an entry to that CheckBox's dictionary. When the Grid needs to know what column the CheckBox is in, it looks the value up from that dictionary. When you set Grid.IsSharedSizeScope to True on an object, that object's dictionary will contain a new property - a dictionary that contains widths/heights for each SharedSizeKey.
I should emphasize that this is my mental model. I haven't sat down with Reflector and looked at the actual implementation of Register, GetValue, and SetValue to figure out how they actually work. I may be wrong about the details. But it's a model that accurately predicts how this stuff behaves, so it's good enough.
The concept of storing property values in dictionaries is pretty weird to C# programmers. It's old hat to Python programmers, though. In Python, all class properties - all objects, in fact - are stored in dictionaries, and so you can get to their value either through property accessors or just by looking them up. Dependency properties and attached properties are just another way in which .NET, having stolen everything Java had that was worth stealing, is now plundering Python. (Or from wherever Python plundered them from.) Learning Python has made me a much better C# programmer; I recommend it to any C# developer who hasn't done it yet.
Here is a tutorial on dependency properties http://www.wpftutorial.net/DependencyProperties.html that explains a little bit about how they work.
The short explanation of why the DependencyProperty object is in a static field is that it represents the description of the property, not the value of the property. Each DependencyObject has a mapping from DependencyProperty objects to their values.
This is also how attached properties work. Because each DependencyObject is storing a mapping from any DependencyProperty to a value, any type can create a new DependencyProperty and set it on any existing DependencyObject.
just see this post by joshsmith it has some additional informatin in it
http://joshsmithonwpf.wordpress.com/2007/06/22/overview-of-dependency-properties-in-wpf/
You can see below a very basic example of dependency property that creates a custom control text box in which space will be not allowed means user can not type space into text box.
1) Create a class with the name of ValidatedTextBox and write the following code in this class file:
public class ValidatedTextBox : TextBox
{
public ValidatedTextBox()
{
}
public static readonly DependencyProperty IsSpaceAllowedProperty =
DependencyProperty.Register("IsSpaceAllowed", typeof(bool), typeof(ValidatedTextBox));
public bool IsSpaceAllowed
{
get { return (bool)base.GetValue(IsSpaceAllowedProperty); }
set { base.SetValue(IsSpaceAllowedProperty, value); }
}
protected override void OnPreviewKeyDown(KeyEventArgs e)
{
base.OnPreviewKeyDown(e);
if (!IsSpaceAllowed && (e.Key == Key.Space))
{
e.Handled = true;
}
}
}
2) Now use the above control into your .XAML file
a) Add namespace of custom control text box like below:
xmlns:CustomControls="clr-namespace: ValidatedTextBox;assembly= ValidatedTextBox "
b) Now, use custom control text box like below:
<CustomControls:ValidatedTextBox IsSpaceAllowed="False" x:Name="MyTextBox" />
It will create a custom control text box that will not allow space. So, Basically Dependency property allows to add feature, extend feature of any control.

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