Binding RowDetails in WPF DataGrid - c#

I cant seem to find how to do this.
I dont see why the datacontext for a rowdetailstemplate becomes the datacontext of the datagrid parent. When it cleary should choose the rowitem from the datagrid itemssource.
<DataGrid Grid.Row="1" x:Name="DataGrid" ItemsSource="{Binding Collection}"
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<TextBox Text="{Binding WhyDoesThisBindingUseDataContextOfDatGridParentAndNotTheRowDataObject}"/>
</DataTemplate>
</DataGrid.RowDetailsTemplate></DataGrid>
How can i get the rowdataobject as the datacontext for my template?

Look at the visual tree.
Object which you binds to ItemsSource doesn't apply to RowDetailsTemplate. It takes DataContext of DataGrid Parent.

Related

Using ItemTemplate and DataTemplate creates a button within ListView. Why?

I have a situation with a ListView. Inside the item template there is a DataTemplate and inside the DataTemplate there is a ListViewItem and it's content is bound. When I click I want to select the item but when I hover my mouse over it, it seems like there is a button created with the ItemTemplate and DataTemplate . At the moment, I can select item by clicking somewhere else within the same row, but that doesn't work if I select the button. I use SelectedItem and if you click on the button within the item, the SelectedItem will not fired.
The ListView is linked to an ItemSource, and SelectedItem of the ListView is bound to a property
Further information: language is C#, ide is Visual Studio 2010.
I will leave my xaml code below, Thanks.
XAML
<ListView x:Name="myListView"
Grid.Column="0"
Grid.Row="2"
Height="Auto"
Margin="0,0,0,0"
SelectionChanged="SchemaListView_SelectionChanged">
<ListView.ItemTemplate>
<DataTemplate>
<ListViewItem Content="{Binding Path=Value}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
C#
void ReadData(string id)
{
var data = ExampleData.GetData(id);
myListView.ItemsSource = data.Results;
}
I've tried binding without ItemTemplate and DataTemplate also tried to link source in xaml but that didn't work
You must not have a ListViewItem in the ItemTemplate of a ListView.
When the elements of the ItemsSource collection are not already ListViewItems (which they typically never are), the framework will automatically create a ListViewItem that becomes the "item container" element for each data item. This automatically generated ListViewItem uses the ItemTemplate as its ContentTemplate.
Besides that, use a ListBox instead of ListView when you do not set a ListView's View property.
So instead of a ListViewItem, use a ContentControl or perhaps a TextBlock:
<ListBox ...>
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Value}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
If there is nothing more than a single content element, simply set the DisplayMemberPath property:
<ListBox ... DisplayMemberPath="Value"/>

fill ComboBox with items from different ViewModel

I have a ComboBox binded to DataContext SceneViewModel, but I want to fill it with data from an observableCollection from another ViewModel called GearViewModel.
How do I do this? or is this possible.
Here is the xaml
<UserControl x:Class="MoviePrepper.View.SceneView"
DataContext="{Binding SceneViewModel, Source={StaticResource Locator}}">
<Grid>
<ComboBox ItemsSource="{Binding to observableCollection in GearViewModel}}" SelectedItem="{Binding SceneCollectionView/Equipment, UpdateSourceTrigger=PropertyChanged}"/>
</Grid>
</UserControl>
You can achieve this using a binding like this:
<ComboBox ItemsSource="{Binding GearViewModel.MyCollection, Source={StaticResource Locator}}"
SelectedItem="{Binding Equipment, UpdateSourceTrigger=PropertyChanged}"/>
Where the ItemsSource property binds to the GearViewModel.MyCollection property in your Locator, and the SelectedItem binds to the SceneViewModel.Equipment (as set by the DataContext of the UserControl).
It is not clear exactly what property you had in mind for binding on the SelectedItem property, so I made some assumptions.
Anywho, that should solve the problem with binding your ItemsSource property to a different view model.

How to bind to a source inside a ListBox different from the ItemsSource already specified

I have a ListBox inside a HubSection, whose Items are bound to a class "players" added to my DefaulViewModel via code behind.
First I simply put a TextBox bound to the property "PlayerName" of my class "players".
Now I would like to add a ComboBox with some items that are NOT part of the class players.
Is it possible ? I thought that definind an ItemsSource in the ComboBox would sort of override the ItemsSource of the ListBox, but nothing displays.
The DataContext of the whole page is defined like so:
DataContext="{Binding DefaultViewModel, RelativeSource={RelativeSource Self}}"
Then the HubSection is like so:
<HubSection x:Name="HubSec1">
<DataTemplate>
<ListBox x:Name="ListBox1" ItemsSource="{Binding players}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBox Text="{Binding Path=PlayerName, Mode=TwoWay}"/>
<ComboBox ItemsSource="{Binding Path=ListOfElements}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</DataTemplate>
</HubSection>
If I define the ComboBox in the same way but outside the ListBox, it will display the string elements of "ListOfElements" properly.
But in this ListBox, the ComboBox is empty. So my guess is that having defined an ItemsSource for the ListBox, it is not possible to override it.
I have tried to define a DataTemplate but was not successful doing so, but it might be the good solution (and I did not proceed properly)
What am I missing ?
Edit :
The ComboBox items is an ObservableCollection. It is not part of the "players" class.
Here is how I added these elements to the DefaultViewModel
DefaultViewModel.Add("players", players);
DefaultViewModel.Add("MyItemsList", ListOfElements);
You can walk up the visual tree and bind to an ancestors datacontext:
{Binding Path=PathToProperty, RelativeSource={RelativeSource AncestorType={x:Type typeOfAncestor}}}
EX:
{Binding Path=ListOfItems, RelativeSource={RelativeSource AncestorType={x:Type ListBox}}}
that should give you the datacontext that the listbox has, so assuming your ListOfItems exists in that data context.
Or you can name your control, and then bind to its datacontext by element name:
{Binding ElementName=mySourceElement,Path=ListOfItems}
It can be a little bit tricky to create a good working binding in Windows Apps. A widely used work around is to use the Tag property.
<ListBox x:Name="ListBox1" ItemsSource="{Binding players}" Margin="0,184,0,0" Tag="{Binding Path=ListOfElements}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBox Text="{Binding Path=PlayerName, Mode=TwoWay}"/>
<TextBox Text="{Binding Path=Tag, ElementName=ListBox1}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
A binding to an element wirh the specific name will work always. And the ListOfElements should be in the scope of the ListBox so you can use the Tag property as a proxy. If you need to bind more than one property, you can also use dummy XAML elements:
<Border Tag="{Binding ...}" Name="dummy1"/>

Child dataGrid dataContext is being set to parent dataGrid causing binding Error

I have a parent and Child DataGrid as:
<DataGrid Name="DispositionNCRsGrid"
ItemContainerStyle="{StaticResource MainDataGridItemStyle}"
ItemsSource="{Binding Path=ParentSource}"
>
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<DataGrid SelectionMode="Single"
ItemsSource="{Binding MyItemSource}"
Style="{DynamicResource MainDataGridStyle}"
HorizontalAlignment="Center" >
Now the problem is Child Grid is looking MyItemSource inside ParentSource instead of current viewmodel.
How do I reset the Child dataGrid to access the data from my current ViewModel
If you want to get MyItemSource for detail DataGrid from the same view model that main DataGrid takes ParentSource then you can use RelativeSource binding and go up the visual tree to find parent DataGrid and use its DataContext
ItemsSource="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGrid}}, Path=DataContext.MyItemSource}"

Silverlight: Access parent data context from DataTemplate?

I'm using Silverlight 4. I have an ItemsControl with a custom DataTemplate. From that DataTemplate, I would like to bind to something in the UserControl's DataContext - not the DataContext of a specific element in the items control. Is there a way to do this?
This should answer your question : Access parent DataContext from DataTemplate
<ItemsControl x:Name="level1Lister" ItemsSource={Binding MyLevel1List}>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content={Binding MyLevel2Property}
Command={Binding ElementName=level1Lister, Path=DataContext.MyLevel1Command}
CommandParameter={Binding MyLevel2Property}>
</Button>
<DataTemplate>
<ItemsControl.ItemTemplate>
</ItemsControl>

Categories