Is it possible to use binding inside other binding? - wpf

Is it possible to write something like this
<TextBlock Text="{Binding Path=TextSource, StringFormat='{Binding Path=StringFormat}' }"
Or the single way is to have three properties: one for some value and other for string presentation of this value, third for format string. In this case TextBox binds with string representation of value. String presentation changes when format string changes.

Yes, it is possible in general and no for your case it is not possible because StringFormat is not Dependency Property.
Binding only works on Dependency Properties.
If you wish that to work create a resource dictionary of type Freezable and let it inherit the actual DataContext. Futhermore use StaticResource extension to set StringFormat in Binding.
StringFormat is not DependencyProperty but it doest accept {StaticResource someKey}.
It's a workaround. But it would work.
Another alternative solution would be attached property.
Attached properties are bindable. You would need to listen to property changed event of your attached property and change the StringFormat inside the handler.

Related

WPF Binding Collection with Index

I'm trying to use a collection that is a property of another collection to bind to a listbox. The following works fine
<ListBox ItemsSource="{Binding Path=Locations[0].Buildings}">
the problem is that I need a dynamic index and
<ListBox ItemsSource="{Binding Path=Locations[index].Buildings}">
where index is an integer in my viewmodel, does not work. Does anyone know how I can associate the index in my xaml with the property in my viewmodel?
where index is an integer in my viewmodel, does not work. Does anyone know how I can associate the index in my xaml with the property in my viewmodel?
One simple option would be to just expose a CurrentLocation property within your ViewModel, which was effectively Location[index]. You could then bind to it directly.
A binding within a binding is not possible, So in XAML you can't bind to "index".
a. Chris Moser's method, You can create a DependencyProperty that binds to "index" Specify a change listener on the RegisterAttached handler and do your work there.
b. Use a Converter. You can provide index as the ConverterParameter
c. Bind to a POCO property. A POCO property would need its INotifyPropertyChanged signaled by the changer

How to bind a textblock's text through XAML using a property?

I am working on a Silverlight application, and I want to bind the simple text property of textblock through a property of string type.
What I did was:
<TextBlock Text="{Binding Name}"/>
Code behind:
public string Name{get;set;}
Name = "Testing..!";
but it will not work.
To expand on anatoliiG's answer (which will work): Data binding refers to properties on the DataContext property of the current element by default. This means that your
<TextBlock Text="{Binding Name}" />
is actually translated to
Set the value of the Text property to this.DataContext.Name
(DataContext is inherited, so if it is not explicitly set on the TextBlock it will check the parent, then the parent of the parent etc etc)
You can resolve your problem in one of two ways:
You can set the value of this.DataContext on the parent to the parent itself (as anatoliiG suggests). This means that when it looks up this.DataContext.Name it will be checking the Page itself, which is where your Name property is found.
You can change your Binding so it looks at the Page instead of Page.DataContext when it is looking up bindings. You can achieve this using the RelativeSource markup extension:
This translates to:
Find the first ancestor of the TextBlock that is of type Page, and bind to the Name property on that object
As a final note, you will also need to implement INotifyPropertyChanged on your DataContext object if you are going to ever change the value of Name.
Oh, and you should be using view models as the DataContext instead of the Page itself!
Answer to your question is: in Page_Loaded event set LayoutRoot.DataContext = this;. But it is more hack, than good practice.
You should take a look into MVVM pattern and INotifyPropertyChanged and create ViewModel which will contain this property.

get context in converter?

I have a usercontrol whose the context is a given object Foo.
I have a textbox in readonly mode, whose the text changes according to a selected value in a combobox (which is bind two-way). The value of the textbox uses the values of a lot of fields in Foo.
For now, I have written a converter Text="{Binding ComboboxValue, Converter={StaticResource MyTextConverter}}, and code-behind, according to the ComboboxValue, I need to return a string composed of other values of Foo. The problem is I can't access the DataContext in the converter, and I can't pass it.
If I bind the context without Path (using Text="{Binding Converter={StaticResource ConnectionStringTextConverter}}), it won't trigger every time my value in the combobox changes (normal).
So, is it possible to it that way ? Or I'm forced to use the Selected event of the combobox ?
Thanks
PS: Actually, what I need is to bind the Text property of the textbox on my DataContext (no Path), but I need the binding to be evaluate each time a property change of the object change. Is this possible ?
You could use the DataContextProxy utility class like this:
Text={Binding ComboBoxValue, Converter={StaticResource MyTextConverter}, ConverterParameter={StaticResource DataContextProxy}}
and then in your converter grab the converter parameter and cast it to a DataContextProxy and use its DataSource property.

Is there any way to set binding for the StringFormat as well?

<TextBox Text="{Binding Path=Double, StringFormat=F3}"/>
StringFormat in the below statement is hard coded. But it will change according to the culture and Customized settings. How can we se the rounding or String format using Dependency property or normal property? This can be applied to TextBox, Label , TextBlock etc where ever we wish to use the String formatting.
No, you can't bind StringFormat, since it's not a dependency property. When you doing something more serious than basic formatting consider two options:
Option 1. Make your ViewModel (i.e. binding source) return data in a most convenient way.
Option 2. Consider using custom value converters.

How does a XAML definition get turned into an object instance?

XAML allows you to specify an attribute value using a string that contains curly braces. Here is an example that creates a Binding instance and assigns it to the Text property of the TextBox element.
<TextBox Text="{Binding ElementName=Foo, Path=Bar}"/>
I want to extend XAML so that the developer could enter this as valid...
<TextBox Text="{MyCustomObject Field1=Foo, Field2=Bar}"/>
This would create an instance of my class and set the Field1/Field2 properties as appropriate. Is this possible? If so how do you do it?
If this is possible I have a followup question. Can I take a string "{Binding ElementName=Foo, Path=Bar}" and ask the framework to process it and return the Binding instance it specified? This must be done somewhere already to make the above XAML work and so there must be a way to ask for the same thing to be processed.
The Binding class is a Markup Extension. You can write your own by deriving from System.Windows.Markup.MarkupExtension.
ElementName and Path are simply properties on the Binding object.
As for the followup you can create a new Binding in code by instantiating the Binding object. I do not know of a way to process a string through.
take a look at markupextensions
http://blogs.msdn.com/wpfsdk/archive/2007/03/22/blogpost-text-creatingasimplecustommarkupextension.aspx

Resources