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.
Related
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.
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.
I'm trying to databind to a listbox like so:
<ListBox x:Name="MyListBox" Margin="0,0,0,65">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Converter={StaticResource MyConverter}}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
The reason I am binding to the whole object and not a property is because my converter will need multiple properties of the object to build the string that it returns.
This works and my string is returned. But then when I change the ObservableCollection that this is based on the value doesn't change on the screen. If I bind to just a single property and change it, then the value does change.
What can I do differently? I can't bind to a single property since I need the entire object in the converter... And the ConverterParameter is already being used.
Remember, if you bind to the "main" property and the value of the main property itself isn't changed, the binding will have no reason to refresh itself. It has no clue that your converter is actually based off of a sub-property. What you can do is use a MultiBinding where you bind not only the "main" property, but also a specific sub-property. This gives your IMultiValueConverter implementation access to the main data object, but because you're also binding to the sub-property that's changing, will also be refreshed when that sub-property's value changes.
You can try using a MultiBinding which I believe updates whenever any of its Bindings are triggered. You can also use an IMultiValueConverter or just take advantage of the StringFormat of the binding.
A templated control I'm working on uses a ValueConverter like so:
<ListBox>
<ListBox.Resources>
<Controls:CodeDescriptionValueConverter x:Key="CodeDescriptionValueConverter"/>
</ListBox.Resources>
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Converter={StaticResource CodeDescriptionValueConverter}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
This is the default look that I supply in generic.xaml. When I use this control I'll want to pass different format strings into the converter. Is there a way to make that happen without providing the full ControlTemplate?
My first thought was that I could use ConverterParameter with a TemplateBinding to a property on the control, but I discovered that ConverterParameters can't be bound to. Another option could be to get access to the control from the ConvertTo method, then pick off that property. I'm not sure how to do that. Any options that would eliminate the need to completely re-template the control each time I use it would be helpful (it's a lot of Xaml).
In these situations, I generally do one of two things:
1) Bind to an object that has access to both the property you want to bind to the format string. In the the converter you will then have access to both the property and the format string.
2) Add properties to your data object/viewmodel/etc for the format string and the formatted text. Then bind to the formatted text properties. Assuming that you are using INotifyPropertyChanged, keep in mind that you will need to fire the propertychanged event for the formatted text property whenever you change the text or format string properties
What is the easiest way to use a valueconverter with a listbox?
I'm setting the ItemSource to a List<> of objects at runtime, and it displays a textstring from the ToString() method. What I would like, though, is to pass the object through a valueconverter to get a completely different string value.
All the examples I have found makes a big deal of binding the list to something in xaml, and defining styles and templates to redesign the whole box, but I just want my values converted...
Use a data template with something like:
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Converter=....}" />
</...>
That's it. When you don't specify a path in your binding, it simply binds to the current object.