WPF Binding - Self Binding with its own DataContext - wpf

Anyone got a situation to bind the same DataContext to Text property (for example) in TextBlock.
I have to assign the DataContext to reflect some trigger based on the Data values from Datacontext in my style. at the same time, i need to bind with the same DataContext object to get the Text Property After applying some conversion on either IValueConverter/IMultivalueConverter.
As i know {Binding}, just bind with the current datacontext. But in the same scenario how to use converter with it?
Any suggestions will be appreciated.
<TextBlock Style="{StaticResource DataEntryTextBlock1}" Grid.Row="1"
DataContext="{Binding MyField1}"
Text="{Binding MyField1, Converter={StaticResource myConverter}}">
</TextBlock>
This XAML script does not work, as the Text binding is trying to look for the MyField1 variable inside the MyField1.
Thanks,
Vinodh

{Binding} is equivalent to {Binding Path=.} so in you case you can use
Text="{Binding Path=., Converter={StaticResource myConverter}}"
Binding.Path on MSDN
Optionally, a period (.) path can be used to bind to the current source. For example, Text="{Binding}" is equivalent to Text="{Binding Path=.}"

Related

Two way binding in ListBox ItemTemplate

I have a ListBox which DataTemplate is TextBox that can be edited. Where should I set Binding TwoWay? In ItemSource or In TextBox binding? Maybe in both? And how it works inside? Is it inherited? So if I set Binding in ItemSource - is it inherited in TextBox?
<ListBox HorizontalAlignment="Left" ItemsSource="{Binding Commands, Mode=TwoWay}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding Name}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Two way binding should be setup op your item you need to display, in this case the Textbox. Here you need to have coupling back to your datacontext. You might want to consider setting the UpdateSourceTrigger property to PropertChanged.
This way you will always have entered value of your text, even without loosing focus.
The itemsource should not be Two way. One way will do since you probable will be binding to an observable collection. This will only be set once from your datacontext. This will automatically handle the adding and removing of items to your collection.
I'd add your code like this:
<ListBox Margin="10,0,0,0" Width="200" HorizontalAlignment="Left" ItemsSource="{Binding Commands}" >
<ListBox.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Where should I set Binding TwoWay?
You should set this Mode for TextBox like this:
<TextBox Text="{Binding Path=Name, Mode=TwoWay}" />
If I'm not mistaken, the Text property is listed TwoWay mode by default. Therefore, it's construction is not required.
From MSDN:
When used in data-binding scenarios, this property uses the default update behavior of UpdateSourceTrigger.LostFocus.
This means that updates the properties were visible at once, you need to set the property UpdateSourceTrigger to PropertyChanged:
<TextBox Text="{Binding Path=Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
So if I set Binding in ItemSource - is it inherited in TextBox?
No, inheritance will not be, because settings of Binding unique for each dependency property. Inheritance happens when using DataContext, but again, settings unique for each property.

How to bind to a StaticResource with a Converter?

I want to use a Converter to change the value of a StaticResource before assigning it to a property. Is there a way to simulate a Binding that will just set the value of the StaticResource after converting it?
Something like {Binding Value={StaticResource myStatic}, Converter={StaticResource myConverter}}?
This works:
<TextBox Text="{Binding Source={StaticResource myStatic},
Converter={StaticResource myConverter},
Mode=OneWay}" />
Note that you have to bind one way, because the binding requires a path attribute otherwise. This makes sense, as otherwise the binding would have to replace the whole resource...

Change DataContext of specific property inside control - WPF

I have User control which contains TextBox with WaterMark inside
<AdornerDecorator>
<TextBox
Height="20"
Margin="10,0"
Grid.Column="0"
Text="{Binding MainCategoryTextBoxValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Name="MainCatTextBox">
<controls:WatermarkService.Watermark>
<TextBlock VerticalAlignment="Center" x:Name="MainCategoryTextBlock"> </TextBlock>
</controls:WatermarkService.Watermark>
</TextBox>
</AdornerDecorator>
You can see here WatermarkService implementation
https://stackoverflow.com/a/836463/1548347
I want take "MainCategoryTextBlock" textblock inside <controls:WatermarkService.Watermark> and set it DataContext to be same like my UserControl DataContext in order to change Watermark text in RunTime from my ViewModel.
I tried to bind "MainCategoryTextBlock" DataContext with RelativeSource to my UserControl DataContext but I didn`t succeed (maybe syntax error - Im not sure).
DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}"
Do you have any clue how can I solve it?
Thanks
If your UserControl has a name then you can do it like this:
DataContext={Binding ElementName="YourUserControlName", Path=DataContext}
But i can see that you are using your textbox inside an adorner decorator so you can't use FindAncestor in this case because your textbox and your UserControl won't belong to the same visual tree.
You should be setting the data context property of your window to your view model, and bind the text property of your textblock to your view model property.
<TextBlock Text={Binding Path=PropertyOnViewModel} />

WPF: How to bind to the name property

Can i bind to the name property?
This does not seem to work:
<TextBlock Name="FordPerfect" Text="{Binding Path=Name, Mode=OneWay}"/>
Am i doing something wrong?
Edit:
Adding ElementName=FordPerfect" solved the issue. What i don't understand is why only binding to Name required this while other properties don't.
Note: Moved the second (design) issue to another question (where i should have placed in the first time...)
Thanks
I would try this :
<TextBlock Name="FordPerfect"
Text="{Binding ElementName=FordPerfect, Path=Name, Converter={StaticResource conv}, Mode=OneWay}"/>
This way, your TextBlock will be the context of the binding.
If it does not work, watch the Output window, you should find a binding error !
you could have more easily done this:
<TextBlock Name="FordPerfect"
Text="{Binding Name, Converter={StaticResource conv}, Mode=OneWay, RelativeSource={RelativeSource Self}}"/>
As to why: that textbox' DataContext is not automatically the TextBox itself. So binding to Name tries to bind to whateverObjectInDataContext.Name. So either you set the DataContext beforehand like:
<TextBlock Name="FordPerfect" DataContext={Binding RelativeSource={RelativeSource Self}}
Text="{Binding Name, Converter={StaticResource conv}, Mode=OneWay}"/>
... or directly set a Source for the Binding
The issue you're having is a Binding, by default, uses the DataContext of the element it's used on as its source. However you want the binding source to be the TextBlock element itself.
WPF has a class called RelativeSource which, as its name implies, sets the source relative to the binding. One of the relations you can choose is Self which does exactly what you want: sets the source of the binding to the element it's used on.
Here's the code:
<TextBlock Name="FordPerfect" Text="{Binding Name, RelativeSource={RelativeSource Self}}" />
Since you're already setting the source with RelativeSource, you don't need to specify ElementName. You also don't need Mode=OneWay as a TextBlock.TextProperty already defaults to one-way since it's output-only.
Hope this helps!

ValueConverter not invoked in DataTemplate binding

I have a ComboBox that uses a DataTemplate. The DataTemplate contains a binding which uses an IValueConverter to convert an enumerated value into a string. The problem is that the value converter is never invoked. If I put a breakpoint in StatusToTextConverter.Convert(), it never is hit.
This is my XAML:
<ComboBox ItemsSource="{Binding Path=StatusChoices, Mode=OneWay}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Converter={StaticResource StatusToTextConverter}}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
I thought this is how one implicitly binds to the value a DataTemplate is presenting. Am I wrong?
Edit: For context: I intend to display an Image in the DataTemplate alongside that TextBox. If I can't get the TextBox binding to work, then I don't think the Image will work, either.
In some circumstances you must explicitly supply a Path for a Binding. Try this instead:
<TextBlock Text="{Binding Path=.,Converter={StaticResource StatusToTextConverter}}"/>

Resources