Relative Binding in Silverlight - silverlight

I have an ItemsControl in my application. The page associated with the ItemsControl is bound to a view-model. The view-model includes two properties: People and Options. For each person, I want to display a list of options in a ComboBox. The options are defined in my view-model. My code looks like the following:
<ItemsControl ItemsSource="{Binding Path=People}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<ComboBox ItemsSource="Options" DisplayMemberPath="FullName" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
However, because each Item represents a Person, the ComboBox is looking at the Person object for a property called "Options". How do I reference the view model for the from the ComboBox instead of the Person?
Thanks!

You can use the following technique
<ComboBox ItemsSource="{Binding ElementName=LayoutRoot, Path=DataContext.Options}" DisplayMemberPath="FullName" />
Assuming that your LayoutRoot's DataContext is the View Model. If not you can give your ItemsControl a name and use that for the ElementName.

Related

Binding to two dependency properties of the user control which is a ListViewItem

I've created an user control which is a ListViewItem. That control has 2 dependency properties I would like to bind to from my ViewModel. But how am I supposed to do that when I can only bind one thing (collection) to ListView ItemsSource property? How can I bind to ExpanderInfo dependency property? Is there any way to do that or maybe I have made a bad assumption and should have created user control in other way?
Here is my xaml code:
<ListView ItemsSource="{Binding Tasks}" SelectedItem="{Binding SelectedTask}" Height="200" ScrollViewer.VerticalScrollBarVisibility="Disabled">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<tc:TaskTile TaskInfo="{Binding}" ExpanderInfo="{Binding ExpanderStatus}"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
Thank you for your help!
Replace <tc:TaskTile TaskInfo="{Binding}" ExpanderInfo="{Binding ExpanderStatus}"/> with
<tc:TaskTile TaskInfo="{Binding}" ExpanderInfo="{Binding DataContext.ExpanderStatus, RelativeSource={RelativeSource AncestorType=ListView, Mode=FindAncestor}}"/>

WPF bind to collection of controls

I want to do a binding to a collection of homemade custom controls.I've a collection of objects (called Parameters), each one of these should be presented in a panel by a custom control.
I have the following in my main window:
<ItemsControl Grid.Column="1"
ItemsSource="{Binding Path=Parameters}">
</ItemsControl>
And I have a resource file to declare how to view each Parameter object:
<DataTemplate DataType="{x:Type path:Parameter}">
<Grid>
<myControls:MyUserControl
Parameter="{Binding RelativeSource={RelativeSource Self}}">
</myControls:MyUserUserControl>
</Grid>
</DataTemplate>
My control takes a Parameter so I want to bind it to itself for every item in the collection. How can I do that binding?
In a DataTemplate that serves as ItemTemplate in an ItemsControl, the DataContext holds the individual items of the source collection. Hence the binding should look like this:
<myControls:MyUserControl Parameter="{Binding}" />
and the ItemsControl may be written like this to explicitly use the DataTemplate:
<ItemsControl ItemsSource="{Binding Path=Parameters}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<myControls:MyUserControl Parameter="{Binding}" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>

How to bind ListBox to a member of a view model in xaml?

I'm just starting with wpf/vmmv. I've seen examples of binding collections to list boxes. Example: in xaml , in code-behind (e.g. Page) "DataContext = collection.. ".
My view model has more properties than just a single collection that need to be bound to a view. Therefore I'd like to set the view model as DataContext for the view and then, in xaml, bind the view model's collection to a ListBox. Assuming that my view model is set as DataContext and it has a property called 'Customers', what is the correct way of binding the property to a ListBox in xaml?
I tried but it does not work.
Thanks.
Do you mean 'how do you bind a collection to a 'ListBox'? You would do that like this:
<ListBox ItemsSource="{Binding Customers}" />
Or this:
<ListBox ItemsSource="{Binding Path=Customers}" />
If you want to bind the internal values of each instance of the Customer class, you would do something like this:
<ListBox ItemsSource="{Binding Customers}" >
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" />
<TextBlock Text="{Binding Age}" />
<TextBlock Text="{Binding EyeColour}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I guess you want to display the property "Customers", what you have to do is define ItemTemplate of ListBox, define DataTemplate inside ItemTemplate, and binding Customers to a control, just like below:
<ListBox ItemsSource="{Binding}" >
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Customers}"/>
......something else you want display
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

How to bind to parent DataTemplate from within an ItemsControl.ItemTemplate

I have a container type control which contains a number of items. The container control has a DataTemplate defined which also contains a ItemsControl with a DataTemplate for the item. The items however need to bind to something from the container control. A simplified example is given below:
<DataTemplate DataType="{x:Type ContainerType}">
<!-- Display of the container stuff-->
<ItemsControl ItemsSource="{Binding Items, Mode=OneWay}">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type Item}">
<!-- Display of the item stuff -->
<ComboBox Text="Choose a container-level option..."
ItemsSource="{WHAT GOES HERE?}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
How to I bind something at the item level back up to the container level?
You can use a RelativeSource binding
<ComboBox ItemsSource="{Binding SomeCollection,
RelativeSource={RelativeSource
AncestorType={x:Type local:MyContainerControl}}}"/>
What you use for your binding path depends on where the collection is located. If it is located as a DependencyProperty on MyContainerControl, then the above binding works fine. If it is located in the DataContext of MyContainerControl, then you'll need to set the binding path to DataContext.SomeCollection
Maybe use TemplateBinding?
Something like:
{TemplateBinding YourPropertyInTheDataTemplateContext}
I've always been a big fan of ElementName. Basically you make sure you name the outer level control like : x:Name="MainWin" and then you can do something like this:
<DataTemplate>
<StackPanel Orientation="Horizontal">
<ComboBox ItemsSource="{Binding ElementName=MainWin, Path=DataContext.SomeCollection}"/>

Binding a WPF ComboBox to a different ItemsSource within a ListBox DataTemplate

I have a ListBox that contains a textbox and a combobox in its datatemplate:
<ListBox Height="147" Margin="158,29,170,0" Name="PitcherListBox" VerticalAlignment="Top" ItemsSource="{Binding SomeCollectionOfObjects}" Background="Black">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBox Text="{Binding Path=Name}" />
<ComboBox ItemsSource="{Binding LocalArrayOfIntsProperty}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I want to bind the listbox to a collection of objects (which I've done successfully), but I want the combobox in the above datatemplate to have its itemssource set to a local property on the window (array of ints). I still want the combobox to have a two-way bind between its selected item and a property on the collection of objects...
I have the following in code:
PitcherListBox.DataContext = this;
Basically in the end, I want the combobox within the listbox to have a different itemssource than the listbox itself. I can't seem to figure out how to change the ComboBox's ItemsSource in XAML. Can someone provide me some feedback? Thanks!
Try this:
<ComboBox ItemsSource="{Binding LocalArrayOfIntsProperty, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type YourWindowTypeHere}}}" />
Note that you need to replace YourWindowTypeHere with the type of the Window containing the LocalArrayOfIntsProperty! Also remember that you will need to define an xml namespace for that type!

Resources