WPF RowDetailsTemplate SelectedItem and button command - c#

Firstly, I am using the MVVM design pattern. I have a DataGrid, as shown in the first code snippet below, in which the RowDetailsTemplate is set to another grid, the second code snippet below. The itemsource for the parent grid is an ObservableCollection of type Adult and the itemsource for the sub-grid is an ObservableCollection of type Child, which is a property of the each Adult object. I am trying to set the SelectedItem and button command for each grid so it hits the ViewModel associated with the view and I cannot see where I am going wrong here. Any advice would be great.
<DataGrid
AutoGenerateColumns="False"
ItemsSource="{Binding AllAdults}"
SelectedItem="{Binding SelectedAdult}"
RowDetailsTemplate="{DynamicResource RowDetailsTemplate}"
RowDetailsVisibilityMode="Collapsed">
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Command="{Binding Path=DataContext.ShowAdultInfoCommand, RelativeSource= {RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}" Content="Print"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Binding="{Binding Path=AdultId, Mode=OneWay}" Header="Id" IsReadOnly="True" />
</DataGrid.Columns>
<DataTemplate x:Key="RowDetailsTemplate">
<DataGrid
ItemsSource="{Binding AllChildren}"
AutoGenerateColumns="False"
SelectedItem="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}, AncestorLevel=2}, Path=DataContext.SelectedChild}">
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Command="{Binding Path=DataContext.ShowChildInfoCommand, RelativeSource= {RelativeSource FindAncestor, AncestorType={x:Type DataGrid}, AncestorLevel=2}}" Content="Show"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Binding="{Binding Path=ChildId, Mode=OneWay}" Header="Child Id" IsReadOnly="True" />
</DataGrid.Columns>
</DataGrid>

Related

How can I set default value of a Combo in a datagrid but with lot of rows changing the value? WPF C#

Rows is ok, but I need to see the results over the combo, I've tried with selected index, it didn't work.
<DataGrid.Columns>
<DataGridTemplateColumn Header="Cheque/Transf." Width="105" CellStyle="{StaticResource cellStyle}" >
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid>
<ComboBox
FontSize="10"
ItemsSource="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type UserControl}},
Path=DataContext.ChequeTransf}"
DisplayMemberPath="Descripcion"
SelectedValuePath="Descripcion"
SelectedValue="{Binding Path=cTipoTransaccion,Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}"
SelectedIndex="{Binding Path=cbxIdTransaccion,Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}"
></ComboBox>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>

CheckBox in DataGrid

Hi I create this code for understand why if put a checkbox out to datagrid all work but if insert a checkbox into datagrid don't work.
This run correct:
<CheckBox x:Name="checkBox" Content="Test" Margin="0" Command="{Binding SelectCommand}" CommandParameter="{Binding IsChecked, RelativeSource={RelativeSource Self}}"/>
But this not:
<DataGrid x:Name="dataGrid" ItemsSource="{Binding XMLValue}" >
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox x:Name="TestCheckBox" Command="{Binding Path=SelectCommand, RelativeSource={RelativeSource FindAncestor, AncestorType=DataGrid}}" IsChecked="{Binding Path=Selected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
SelectCommand is only a MessageBox.Show
(thank you and sorry for my english)
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox x:Name="TestCheckBox" Command="{Binding Path=DataContext.SelectCommand, RelativeSource={RelativeSource FindAncestor, AncestorType=DataGrid}}" IsChecked="{Binding Path=Selected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
i have tested your code ... you just have to modify your Path in your binding and use DataContext Property of your DataGrid ... not the DataGrid itself, the DataGrid Class doesn't have a property called 'SelectCommand':
Command="{Binding Path=DataContext.SelectCommand, RelativeSource={RelativeSource FindAncestor, AncestorType=DataGrid}}"

Bind datagrid column visibility to a dictionary value

people! I have an issue:
i have an app on MVVM Light with DataGrid:
<DataGrid ItemsSource="{Binding Path=MyCollection, Mode=TwoWay}" AutoGenerateColumns="False" CanUserAddRows="False"
FontSize="14" Name="ItemGrid" SelectionUnit="FullRow" ColumnHeaderStyle="{StaticResource ResourceKey=DataGridColumnHeader}" Background="Transparent"
Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}},UpdateSourceTrigger=PropertyChanged}" Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="4"
CanUserResizeRows="False" SelectionMode="Single" BorderThickness="0">
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<DataGrid
IsReadOnly="True"
AutoGenerateColumns="False"
ItemsSource="{Binding MyItems}"
SelectionUnit="FullRow"
Visibility="{Binding Path=DataContext.RowDetailsVisibility, Mode=TwoWay,Converter={StaticResource BoolToVisibilityConverter}, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"
CanUserResizeRows="False"
CanUserResizeColumns="True"
SelectedItem="{Binding Path=DataContext.SelectedItem, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}">
<DataGrid.Columns>
<DataGridTextColumn Header="ID" Visibility="Collapsed" Binding="{Binding ID}" Width="Auto" CellStyle="{StaticResource ResourceKey=DataGridCell}" />
<DataGridTextColumn Header="Title" Visibility="Visible" Binding="{Binding Title}" Width="Auto" CellStyle="{StaticResource ResourceKey=DataGridCell}" />
</DataGrid.Columns>
</DataGrid>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
<DataGrid.Columns>
<DataGridTemplateColumn Header="Item Pack ID" Width="*" CellStyle="{StaticResource ResourceKey=DataGridCell}">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Id, Mode=TwoWay}" Style="{StaticResource ResourceKey=TextBoxStyle}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Number" Width="*" CellStyle="{StaticResource ResourceKey=DataGridCell}">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Number, Mode=TwoWay}" Style="{StaticResource ResourceKey=TextBoxStyle}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid.Columns>
<DataGrid.ContextMenu>
<ContextMenu Name="contextMenu" Style="{StaticResource ContextStyle}">
</MenuItem>
<MenuItem Header="Packs Columns"
ItemsSource="{Binding PacksCollection}"
DisplayMemberPath="Key"
Command="{Binding Path=DataContext.PacksCommand,
RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"
>
</MenuItem>
<MenuItem Header="Items Columns"
Command="{Binding Path=DataContext.ItemsCommand,
RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"
ItemsSource="{Binding ItemsCollection}" DisplayMemberPath="Key">
</MenuItem>
</ContextMenu>
</DataGrid.ContextMenu>
</DataGrid>
</Grid>
So, if you understand, i have a grid with Packs(Id,Number),each Pack have some Items(Id,Title). I want to have a context menu, which have 2 lists: Packs and Items. In each menu item we can choose what column to show.
ItemsCollection and PacksCollection are Dictionary where String - Column Header(same as in data grid) and bool - visibility state(true for Visible, false for Collapsed).
Question: how to bind MVVM click on menu item, that will change column visibility. I tried some solutions, but they don't worked for me.
I need to change visibility for DataGrid columns(Id,Number) and for RowDetails DataGrid - Id, Title. Help please, i don't think this is so hard.
Thank you.

How to bind WPF combobox selected item with a value converter to a label? Both label and combobox are datagrid columns

I want to bind SelectedItem of Combobox with a value converter to "DataGridTextColumn" after it. I am using MVVM pattern.
<Datagrid>
<DataGrid.Columns>
<DataGridTemplateColumn Header="Left">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox Name="Leftcombo" ItemsSource="{Binding Path=DataContext.Column, RelativeSource={RelativeSource AncestorType=Window}}"
SelectedItem="{Binding SelectedColumn, UpdateSourceTrigger=PropertyChanged}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Right" Binding="{Binding SelectedColumn, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"/>
</DataGrid.Columns>
</DataGrid>
Please note: SelectedColumn is a property in viewmodel bound to Selected item of combobox.
Binding works the way it is in xaml above but, I want to use a value converter on the "DataGridTextColumn Header="Right"" Column.
I think you need to try Mode = TwoWay.
<Datagrid>
<DataGrid.Columns>
<DataGridTemplateColumn Header="Left">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox Name="Leftcombo" ItemsSource="{Binding Path=DataContext.Column, Mode=TwoWay, RelativeSource={RelativeSource AncestorType=Window}}"
SelectedItem="{Binding SelectedColumn, UpdateSourceTrigger=PropertyChanged}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Right" Binding="{Binding SelectedColumn, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</DataGrid.Columns>
</DataGrid>

How to use RelativeSource Binding to create DataGrid binding to Model and ViewModel?

I have a DataGrid which has a DataGridTemplateColumn that uses the ItemsSource binding of the DataGrid, but in the ComboBox of the DataGridTemplateColumn, I want to be able to bind to the ViewModel for the View instead of the ItemsSource.
<DataGrid ItemsSource="{Binding ModelValues, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" >
<DataGridTemplateColumn Header="myHeader" Width="200">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox DisplayMemberPath="Value" SelectedValuePath="Key" IsEnabled="False"
SelectedValue="{Binding myID, Mode=TwoWay}"
ItemsSource="{Binding Path=myList,
RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:ViewModel}}}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox DisplayMemberPath="Value" SelectedValuePath="Key" IsEnabled="False"
SelectedValue="{Binding myID, Mode=TwoWay}"
ItemsSource="{Binding Path=myList,
RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:ViewModel}}}" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
</DataGrid>
The ViewModel has a ModelValues property as well as myList property. The ModelValues is used for the ItemsSource of the DataGrid and I want to use myList for the ComboBox ItemsSource.
How would I change my RelativeSource command so that it would work?
Bind to the datacontext of the grid :
<DataGrid ItemsSource="{Binding ModelValues, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" >
<DataGridTemplateColumn Header="myHeader" Width="200">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox DisplayMemberPath="Value" SelectedValuePath="Key" IsEnabled="False"
SelectedValue="{Binding myID, Mode=TwoWay}"
ItemsSource="{Binding Path=DataContext.myList,
RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox DisplayMemberPath="Value" SelectedValuePath="Key" IsEnabled="False"
SelectedValue="{Binding myID, Mode=TwoWay}"
ItemsSource="{Binding Path=DataContext.myList,
RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
</DataGrid>

Categories

Resources