TreeListView.RowDetailsTemplate new for each row - wpf

Im close to my solution but i cant figure out my last step.
I have a RowDetailsTemplate for each row in a RadTreeListView.
My Probplem is I can figure out how to bind it. Im binding it to CurrentSelected but now evrytime I click on a other row the RowDetailsTemplate changes ofcourse. MY XAML is to big to post it so I ll show some examples.
<RadTreeListView Name="positionenDataGrid"
HierarchyColumnIndex="3"
ItemsSource="{Binding Path=Model.ModelChildList}"
SelectedItem="{Binding Path=CurrenPosition}">
<RadTreeListView.ChildTableDefinitions>
<TreeListViewTableDefinition ItemsSource="{Binding PositionChildList}" />
</RadTreeListView.ChildTableDefinitions>
<RadTreeListView.Columns>
<columns:CustomToggleButtonColumn x:Name="ExpanderColumn" Header="DetailView" DataMemberBinding="{Binding IsPositionExpanded}" ToggleButtonVisibility="{Binding Path=CanHavePositionen}"/>
</RadTreeListView.Columns>
<RadTreeListView.RowDetailsTemplate>
<DataTemplate>
<Views:DetailPositionView HorizontalAlignment="Left" />
</DataTemplate>
</RadTreeListView.RowDetailsTemplate>
</RadTreeListView>
Example of Binding in DetailPositionView;:
Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Views:ParentView}}, Path=DataContext.CurrenPosition.Number}"
If I open two RowDetailsTemplates at the same time they have both the same Content because I bind on the SelectedItem. The question now is: How can I give them each Data of each Row without SelectedItem?

DataContext of your DetailPositionView is the row data. So just doing
Value="{Binding Number}"
will do the trick

Related

How to add a tooltip for a datagrid and show the converted value of the datagrid in tooltip?

I have DataGrid and one of the DataGrid columns looks like this.
<ig:TextColumn HeaderText="{Binding CARTONS, Source={StaticResource Messages}, Converter={StaticResource MessageConverter}}"
Key="Collumn1"
AllowToolTips="Always">
<ig:TextColumn.ToolTipContentTemplate>
<DataTemplate>
<TextBlock Text="{Binding Self}, Converter={StaticResource TransferCollumnToCrlfDelimitedList}}"/>
</DataTemplate>
</ig:TextColumn.ToolTipContentTemplate>
</ig:TextColumn>
The problem is I need show convert the column's value to a list of sub-value of the column. I tried using self. Obviously, it doesn't work.
How can I solve my task? Is any possible.
Remove SELF
Use just {Binding} and you will get the same DataContext as the parent control

WPF Datagrid ComboBox DataBinding

Can anyone tell me why this works;
<DataGridTemplateColumn Header="Supplier">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox DisplayMemberPath="SupplierName" SelectedValuePath="SupplierID"
SelectedValue="{Binding SupplierID}"
ItemsSource="{Binding Path=DataContext.Suppliers, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
but this doesn't;
<DataGridComboBoxColumn Header="Combo" DisplayMemberPath="SupplierName" SelectedValuePath="SupplierID"
SelectedValueBinding="{Binding SupplierID}"
ItemsSource="{Binding Path=DataContext.Suppliers, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" />
Second snippet does not show the list of SupplierName on edit...
It's because a DataGridComboBoxColumn isn't a user interface element, but ComboBox is.
In the first example, because your ComboBox is part of the visual tree, RelativeSource can do what it's supposed to do: walk up the UI tree looking for the item you've asked for. But in the second example, the DataGridComboBoxColumn is a DependencyObject but it's not an actual UI element - it's an object that describes something about the UI element.
You could try using ElementName instead, and give a name to your root window. Or, you might be able to get away with just:
<DataGridComboBoxColumn ...
ItemsSource="{Binding Path=Suppliers}" />
The DataContext will flow down from the window to the grid, so unless you've overidden it with something else at this point in the UI, it'll still be available.
Or if that doesn't work, you might want to add the relevant collection to a resource dictionary so you can get it with a Source={StaticResource suppliers} in the binding.
The reason is that the ItemsSource for the DataGridComboBoxColumn can not be found.
You will need to use the RelativeSource Binding and point it to the correct DataContext AncestorType. This will take some trial and error to find the DataContext that contains your list to satisfy your ItemsSource.

Append DataGrid inside of DataGrids RowDetailsTemplate

this appears to bind, but rows in Details Grid are empty. Something is off/missing?
I've also tried {Binding SubCustomers}
SubCustomers is a List on parent object.
I am able to bind this way to single Fields such as FirstName etc.. just not the subcollection..
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<DataGrid AutoGenerateColumns="True" ItemsSource="{Binding Source=SubCustomers}" />
</DataTemplate>
</DataGrid.RowDetailsTemplate>
The problem is that you are trying to bind to a property on the DataContext of the parent, not on that particular row. So, the DataContext of the RowDetails is the row item, and in order to get the parent's property, you need to use RelativeSource bindings. If you bind to the DataContext of the parent, you can then "dot-down" to the property you actually care about:
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<DataGrid AutoGenerateColumns="True"
ItemsSource="{Binding DataContext.SubCustomers, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" />
</DataTemplate>
</DataGrid.RowDetailsTemplate>

Problem with DataTemplate and ObjectDataProvider refresh

I have a problem with a edit templete of cell in a WPF datagrid (WPF Toolkit). The template is builded with a ComboBox and the ItemsSource of
ComboBox are loaded at runtime.
This is the mean code...
<ObjectDataProvider x:Key="dataValuesProvider" MethodName="GetValues" />
<toolkit:DataGrid
ItemsSource="{Binding Path=MyItems}">
<toolkit:DataGridTemplateColumn
Header="Property1">
<toolkit:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Property1, ValidatesOnDataErrors=true}"/>
</DataTemplate>
</toolkit:DataGridTemplateColumn.CellTemplate>
<toolkit:DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox
SelectedValue="{Binding Path=Property1, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}"
IsEditable="True"
IsSynchronizedWithCurrentItem="False"
ItemsSource="{Binding Source={StaticResource dataValuesProvider}, Mode=OneWay}"
/>
</DataTemplate>
</toolkit:DataGridTemplateColumn.CellEditingTemplate>
</toolkit:DataGridTemplateColumn></toolkit:DataGrid>
Now, I have this problem.
I have to update the dataValuesProvider with different value on each rows. Then I have insert a reset of dataValuesProvider (dataValuesProvider=null) on selectionchanged event of datagrid.
(The dataValuesProvider will load after a input on a specific cell of the selected row).
This is the problem: when I reset the dataValuesProvider (on selectionchanged of a new row) it's modified the SelectedValue of ComboBox and the Property1 of previous row is cleared.
I think that there is this behavior becouse the editing template of cell not update the binding associations until I edit the cell. It's right?
How can I do to avoid this problem?
I have not yet resolved
however I have defined a simple project that show the problem.
You can download it from this link: http://pollosky.it/wp-content/uploads/2009/12/ObjectProviderTest.zip
Try to selectvalue from the second cell of the first row and then go to the second row. The value of property of first row is cleared!
How can I do?

Problem binding DataGridComboBoxColumn.ItemsSource

I have 3 tables:
Item - which is the DataContext - it has a navigation column Group
Group - has a navigation column Category.
I want to have in the DataGrid both (Category & Group) columns and when I choose a category it should display in the group col only the Category.Groups.
Here is the code I am working on:
<tk:DataGrid AutoGenerateColumns="False" ItemsSource="{Binding}">
<tk:DataGrid.Columns>
<!--Works-->
<tk:DataGridComboBoxColumn
Header="Categroy"
DisplayMemberPath="Title"
SelectedValuePath="CategoryId"
SelectedValueBinding="{Binding Group.Category.CategoryId}"
ItemsSource="{Binding Context.Categories,
Source={x:Static Application.Current}}"
/>
<!--Look at these two things:-->
<!--This does work-->
<tk:DataGridTemplateColumn>
<tk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ItemsControl
ItemsSource="{Binding Group.Category.Groups}">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type data:Group}">
<TextBlock Text="{Binding Title}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
</tk:DataGridTemplateColumn.CellTemplate>
</tk:DataGridTemplateColumn>
<!--But this does NOT work, even it's the same source-->
<!--Notice I even tried a dummy converter and doesnt reach there-->
<tk:DataGridComboBoxColumn
Header="Group"
DisplayMemberPath="Title"
SelectedValuePath="GroupId"
ItemsSource="{Binding Group.Category.Groups,
Converter={StaticResource DummyConverter}}"
SelectedValueBinding="{Binding Group.GroupId}"
/>
</tk:DataGrid.Columns>
</tk:DataGrid>
Update
Would you say the problem is that the ItemsSource property cannot be set to a non-static Binding?
I suspect so because even I set the ItemsSource to {Binding} with the DummyConverter it doesn't stop in the converter; and in the Category ComboBox it works fine.
The columns in the datagrid don't have a datacontext, as they are never added to the visual tree. sound a bit weird but have a look at vince's blog, its got a good example of the visual layout. once the grid is drawn the cells have a data context and you can set the combo boxes items source in them using normal bindings (not static resources..)
You can access the combo box items source as such:
<dg:DataGridComboBoxColumn>
<dg:DataGridComboBoxColumn.EditingElementStyle>
<Style TargetType="ComboBox">
<Setter Property="ItemsSource" Value="{Binding Path=MyBindingPath}" />
</Style>
</dg:DataGridComboBoxColumn.EditingElementStyle>
</dg:DataGridComboBoxColumn>
Have a look here and also here for some code. You will also need to set the items source for the non edting element as in this post
I was using MVVM and I wanted to bind the ItemSource of the column to a collection of objects in the window data context. I must have tried 10 different ways and nothing worked until I found this answer.
The trick is to define a CollectionViewSource outside the grid and then reference it inside the grid using StaticResource. For example,
<Window.Resources>
<CollectionViewSource x:Key="ItemsCVS" Source="{Binding MyItems}" />
</Window.Resources>
<!-- ... -->
<DataGrid ItemsSource="{Binding MyRecords}">
<DataGridComboBoxColumn Header="Column With Predefined Values"
ItemsSource="{Binding Source={StaticResource ItemsCVS}}"
SelectedValueBinding="{Binding MyItemId}"
SelectedValuePath="Id"
DisplayMemberPath="StatusCode" />
</DataGrid>

Resources