Silverlight Binding - silverlight

I've a Silverlight page using a MVVM behind it to handle all the data bits going on.
The data context is set for the page using:
DataContext="{Binding AddNewClientViewModel, Source={StaticResource ServiceLocator}}"
ServiceLocator being a service that allows me to create and inject the appropriate VM using an IoC container.
This all works fine.
Now I have a DataForm like so:
<df:DataForm CurrentItem="{Binding NewClient}" AutoGenerateFields="False" >
<df:DataForm.NewItemTemplate>
<DataTemplate>
<StackPanel>
<df:DataField>
<TextBox Text="{Binding ClientName}" />
</df:DataField>
<df:DataField>
<TextBox Text="{Binding Property_on_the_VM_not_on_NewClient}" />
</df:DataField>
</StackPanel>
</DataTemplate>
</df:DataForm.NewItemTemplate>
</df:DataForm>
OK, so this dataform binds to the NewClient property on my ViewModel. The first DataField binds to the NewClient.ClientName. The second DataField I'd like to bind to a property that hangs of the root ViewModel.
I know there is the 'Source' parameter that you can pass in when binding, if I had a static resource of the VM or similar I could point it to that, but I don't. How can I link this binding up with property on the parent VM?
Edit
After a post by Jobi below, I've tried the following:
<TextBox DataContext="{Binding DataContext, ElementName=root}" Text="{Binding MyProperty}" />
And my top level control:
x:Name="root"
DataContext="{Binding AddNewClientViewModel, Source={StaticResource ServiceLocator}}"
No dice with getting this to work...

What you need is a DataContextProxy which was created by Dan Wahlin. The problem is that once you get into the data form, you have a new data context. There is no easy way to reach back up to the view's data context. The data context proxy allows you to easily do this and I've used it quite a bit found it works great.

On the second TextBox you can do an ElementName binding to the root element where the Parent VM has already DataContext to.
<TextBox DataContent="{Binding DataContext, ElementName=rootLevelControl}" Text="{Binding property}"

Related

How to define DataContext in my Resource File or under Window.Resource tag?

I have this binding:
<Window x:Name="_local">
<TextBox x:Name="txtVendorName" DataContext="{Binding ElementName=_this, Path=VendorObject}" Width="200" Height="50" BorderBrush="Black" Text="{Binding Path=VendorName}" />
if i have 50 textboxes and label which I need to bind, do I need to put DataContext for all??
Is there a way I can centralize this DataContext and only define Text/Content for my objects?
I don't want to define DatContext to my Grid. So how can I define DataContext in my?
<Window.Resources></Window.Resources>
If I am guessing your actual requirement right, then what you want is all 50 labels and textblocks should be bound to the data context which is VendorObject from _this object. Although I couldnt really guess what _this object is.
Well DataContext is an Inherited Dependency Property (IDP) what they mean is when a visual parent is set with a data context its data context is acquired by all the children below that visual.
So if you put some Panel in your window and set its data context once with your binding DataContext="{Binding ElementName=_this, Path=VendorObject}" and then put all those 50-100 textblocks and labels under that panel then they will automatically acquire that vendor-object as the data context.
So
<StackPanel DataContext="{Binding ElementName=_this, Path=VendorObject}">
<TextBlock Text="{Binding Path=VendorName}" />
<TextBlock Text="{Binding Path=VendorId}" />
<TextBlock Text="{Binding Path=VendorLocation}" />
.... <!--Put all the 50 UI items here to use same data context -->
</StackPanel>
I hope I guessed correctly of what you need.
Now answering you next question,
So how can I define DataContext in my?
<Window.Resources></Window.Resources>
You cant. But you can create an instance of VendorObject class and give it a resource Key, but thats simply a bad design.

Silverlight Treeview SelectedItem TwoWay binding causing error in blend

I have a Treeview in a Silverlight 4 project, and I want to bind to its SelectedItem. When I do a binding to SelectedItem (Mode=TwoWay) its throwing an error in blend because SelectedItem is readonly, which is causing my XAML to not render. I don't ever want to SET the SelectedItem property, I just want to know when it changes via UI interaction. In WPF, I would just bind its SelectedItem using Mode=OneWayToSource, but Silverlight does not support that mode (afaik).
Treeview :
<controls:TreeView ItemsSource="{Binding Repository.MajorClasses}" SelectedItem="{Binding SelectedItem, Mode=TwoWay}" />
Is there a workaround that anyone has used? And anyone know why OneWayToSource is omitted from Silverlight?
It's really readonly, so you cann't do that. You can use TreeView as base control and create CustomTreeView with implementation of bindable SelectedItem. Or create own behavior(attached property). Or use some third party control (f.i. telerik).
If you just want your VM to be informed when the user changes the selection, you should be able to do exactly what you are doing (a two way binding).
I have this working in Visual studio so, I suggest trying it from there, might just be a problem with Blend. VS intellisense doesn't suggest SelectedItem when typing in the XAML editor but that doesn't stop it from working.
The bound property in your VM is definately of the right type (MajorClass by the looks of it)?
What you need to do is make use of an Interaction Trigger and bind it to the SelectedItemChangedevent as follows:
<sdk:TreeView x:Name="ModuleNavigationItemWrappersTreeView" ItemsSource="{Binding ModuleNavigationItemWrappers}">
<sdk:TreeView.ItemTemplate>
<sdk:HierarchicalDataTemplate ItemsSource="{Binding Children}">
<StackPanel Orientation="Horizontal" Margin="0,2,0,2">
<Image Source="/VanguardFinancials.Common;component/Images/icons/flag_blue.png" />
<TextBlock Margin="2,0,0,0" Text="{Binding ItemDescription}"></TextBlock>
</StackPanel>
</sdk:HierarchicalDataTemplate>
</sdk:TreeView.ItemTemplate>
<interactivity:Interaction.Triggers>
<interactivity:EventTrigger EventName="SelectedItemChanged">
<interactivity:InvokeCommandAction Command="{Binding TrackSelectedModuleNavigationItemWrapper}" CommandParameter="{Binding ElementName=ModuleNavigationItemWrappersTreeView}" />
</interactivity:EventTrigger>
</interactivity:Interaction.Triggers>
</sdk:TreeView>
Visit this for more information about Behaviors and Triggers. Hope this helps.

WPF XAML Binding

Hello
I have a problem with a binding that I want to do and can't find any information on how to do it.
Basically I want to bind an object to a property of another object.
For example
<TextBox Text="test" Tag="{Binding ElementName=TxtBx2}" x:Name="TxtBx1"/>
<TextBox Text="test" x:Name="TxtBx2"/>
This is kind of weird but it would help on the code that i'm implementing, so on a property of one object I want to have another object bind in xaml.
I don't know if this is possible, any pointers would be helpful
Thanks, Ruben
That is how you do it; you just need to specify the Path.
<TextBox Text="test" Tag="{Binding ElementName=TxtBx2, Path=Text}" x:Name="TxtBx1"/>
<TextBox Text="test" x:Name="TxtBx2"/>
If you are wanting the DataContext of the TextBox; then your Path would change accordingly.
<TextBox Text="test" Tag="{Binding ElementName=TxtBx2, Path=DataContext}" x:Name="TxtBx1"/>
<TextBox Text="test" x:Name="TxtBx2"/>
If you are needing to use the Tag property within a WPF application you might want to re-evaluate your approach as I have yet to use the Tag property since moving from WinForms as that need has been replaced by leveraging the data binding functionality within WPF.
UPDATE:
If your goal is to bind to a given control versus a property on the control; then don't specify the property name within the Path.
Based on your goal; attached behaviors would be a better approach and allow you to wrap the functionality within the extended DataGrid.
<TextBox Text="test" Tag="{Binding ElementName=TxtBx2,Path=Text}" x:Name="TxtBx1"/>
<TextBox Text="test" x:Name="TxtBx2"/>
Assuming you want the value of the Text property of TxtBx1 to be the value of the Text property in TxtBx2, you would use:
<TextBox x:Name="TxtBx1" Text="{Binding ElementName=TxtBx2, Path=Text}" />
<TextBox x:Name="TxtBx2" Text="test" />
Update
Assuming (possibly incorrectly again!) that you want to bind the TxtBx1 element to the Tag of TxtBx2, you would use:
<TextBox x:Name="TxtBx1" Text="test" />
<TextBox x:Name="TxtBx2" Tag="{Binding ElementName=TxtBx1}" Text="test" />
Just out of interest, why do you want to do such a thing?
Update 2
Assuming that you have a Datagrid that you've extended from the wpftoolkit datagrid and a user control that is a pager for that Datagrid, and when you move to another page you need to do some processing on the datagrid, then why don't you just either update the datagrid in your page change event (if using code behind), or update the items that the datagrid is bound to in your page change verb on your view model (if using MVVM)?
Well, it does make sense to bind to an entire object(not to any specific property) with items control such as this:
<ListBox x:Name="pictureBox"
ItemsSource=”{Binding Source={StaticResource photos}}" …>
......
</ListBox>

Correct way to do DataBinding in a WP7 UserControl

I'm building a Windows Phone 7 App. So, I'm using SilverLight 3(.7) and I'm having a bit of a problem with the UserControls that I've built. Here's how I'm doing it now:
UserControl has a DependencyProperty named Number
<UserControl x:Class="MyUserControl" x:Name="myUserControl">
<TextBlock Text="{Binding ElementName=myUserControl, Path=Number}"/>
</UserControl>
To use it I'm simply doing:
<MyUserControl Number="{Binding ElementName=MyPage, Path=SomeNumber}">
<MyUserControl Number="{Binding ElementName=MyPage, Path=SomeOtherNumber}">
This all works great, but if I add a name to one of the two instances of my control, things go wacky. For example:
<MyUserControl x:Name="SomeNumberControl"
Number="{Binding ElementName=MyPage, Path=SomeNumber}">
<MyUserControl Number="{Binding ElementName=MyPage, Path=SomeOtherNumber}">`
Then the data doesn't show up. It appears that the name given overrides the name specified in the UserControl and the bindings don't work.
So, I tried to do binding through the datacontext. And setting the DataContext to the UserControl.
so, my control became:
<UserControl x:Class="MyUserControl"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<TextBlock Text="{Binding Number}"/>
</UserControl>
With this nothing gets bound. It's like the datacontext is never set and even weirder when I put this control in another user control that I created, It appears that the parent control is now somehow bound to the MyUserControl instance.
So when I do the following:
<MyPage>
<MyUserControl Number={Binding SomeNumber}"/>
I get the error,
SomeNumber not found in type MyUserControl.
It's as if the binding for the parent control is now the instance of MyUserControl. Am I just doing something fundamentally wrong in how I'm doing bindings in my user control, or is this something strange with SilverLight 4 and WP7.
Any help on this is greatly appreciated.
If you have a DependecyProperty in your codebehind called Number you can set
DataContext = this;
That should allow you to bind directly to your Number property from TextBlock.
<TextBlock Text="{Binding Number}"/>

Binding parent container props to content child control in Silverlight

Example:
<UserControl x:Name="userControl"
<StackPanel x:Name="container" Margin="0">
<TextBox Text="{Binding Path=SettingValue, RelativeSource={RelativeSource Mode=Self}}"/>
</StackPanel>
</UserControl>
UserControl contains SettingValue dependency property, TextBox doesn't,
so this example won't work.
I could've done this if I had AncestorType, like in WPF:
RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControlType}
Is there any possibility to bind to UserControl.SettingValue property?
Did you try the following? Use the ElementName source (the syntax might be a bit off).
<TextBox Text="{Binding Path=SettingValue, ElementName=userControl"/>
The answer I've found here:
Binding Silverlight UserControl custom properties to its' elements

Resources