How do I Inherit DataGridColumns - wpf

I'm writing a UserControl with two DataTemplates in the resources:
DataTemplate 1
<DataTemplate x:Key="Template1">
<DataGrid ItemsSource="{Binding}" SelectionChanged="DataGridSelectionChanged">
<DataGrid.Columns>
<DataGridTemplateColumn Header="FilePath" Width="Auto" SortMemberPath="FilePath">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Padding="4,1" Text="{Binding FilePath}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="FileSize" Width="Auto" SortMemberPath="FileSize">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Padding="4,1" Text="{Binding FileSize}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</DataTemplate>
DataTemplate2
<DataTemplate x:Key="Template2">
<DataGrid ItemsSource="{Binding}" SelectionChanged="DataGridSelectionChanged">
<DataGrid.Columns>
<DataGridTemplateColumn Header="FilePath" Width="Auto" SortMemberPath="FilePath">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Padding="4,1" Text="{Binding FilePath}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="FileSize" Width="Auto" SortMemberPath="FileSize">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Padding="4,1" Text="{Binding FileSize}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="FileCreator" Width="Auto" SortMemberPath="FileCreator">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Padding="4,1" Text="{Binding FileCreator}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="FileCreated" Width="Auto" SortMemberPath="FileCreated">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Padding="4,1" Text="{Binding FileCreated}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</DataTemplate>
With a DataTemplateSelector I decide which DataTemplate should be used. Everything just works fine.
But as you can see DataTemplate2 has the same two cells as DataTemplate1 plus two additional. This is just an small example. In my application DataTemplate1 has around 15 columns. And with DataTemplate2 there are another 10 columns.
My question now is: Is there a possibility that I can inherit(or so) the columns from another DataGrid inside a DataTemplate and add additional columns?

You can add the Columns as Resource and Refer them in the DataGrid as resources. Make sure you should marked them as x:Shared as false to avoid the conflict.
Refer below code.
<DataGridTemplateColumn x:Key="FilePath" x:Shared="False" Header="FilePath" Width="Auto" SortMemberPath="FilePath">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Padding="4,1" Text="{Binding FilePath}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn x:Key="FileSize" x:Shared="False" Header="FileSize" Width="Auto" SortMemberPath="FileSize">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Padding="4,1" Text="{Binding FileSize}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataTemplate x:Key="Template1">
<DataGrid ItemsSource="{Binding}" SelectionChanged="DataGridSelectionChanged">
<DataGrid.Columns>
<StaticResource ResourceKey="FilePath"/>
<StaticResource ResourceKey="FileSize"/>
</DataGrid.Columns>
</DataGrid>
</DataTemplate>
<DataTemplate x:Key="Template2">
<DataGrid ItemsSource="{Binding}" SelectionChanged="DataGridSelectionChanged">
<DataGrid.Columns>
<StaticResource ResourceKey="FilePath"/>
<StaticResource ResourceKey="FileSize"/>
<DataGridTemplateColumn Header="FileCreator" Width="Auto" SortMemberPath="FileCreator">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Padding="4,1" Text="{Binding FileCreator}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="FileCreated" Width="Auto" SortMemberPath="FileCreated">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Padding="4,1" Text="{Binding FileCreated}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</DataTemplate>
Refer this link as well WPF DataGrid Columns in Style or resource

AFAIK there is no inherit possibility in columns in datagrid, but what I suggest is --
Create a customGrid control and add all the common columns to it.
Use this grid in your template and add the columns that make sense for that template.
So you will have, BaseGrid with columns 1,2,3,4 and then you can use this baseGrid and add columns 5,6 in one template and 7,8 in another template.
You will have 2 resulting grids, one with columns 1,2,3,4,5,6 and another with 1,2,3,4,7,8
DataGrid.Columns is a collection of columns and you can add stuff into it whenever you wish for.

Related

Datagrid/Listview rowspan in Xaml

I want to create a datagrid similar to the image. Please help me to do datagrid/listview rowspan or cell merging in wpf. Sample image and xaml code are as follows,
<DataGrid Name="DG" AutoGenerateColumns="False" ItemsSource="{Binding TextandNumbers}" >
<DataGrid.Columns>
<DataGridTemplateColumn Header="B">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Number}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="C">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Texts}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="D">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Number}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="E">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>

WPF - Combobox in header

I have a datagrid like in the following.
.............
<DataGridTemplateColumn >
<DataGridTemplateColumn.Header>
<StackPanel Orientation="Horizontal">
<TextBlock Text="SomeTopic"/>
<ComboBox/>
</StackPanel>
</DataGridTemplateColumn.Header>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
I want that column to have a combobox in its header. At the same time, I want all the rows in the datagrid to have comboboxes under the same column.
That's what I've written to achieve this. Everything is fine. But in the header what it shows is "System.Windows.Controls.Stackpanel".....It does not show the combobox in the header....not even the topic "sometopic".
where have I gone wrong ?
Can someone answer pls ?
You need to use the DataGridColumn.HeaderTemplate Property instead.
<DataGridTemplateColumn>
<DataGridTemplateColumn.HeaderTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="SomeTopic"/>
<ComboBox/>
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.HeaderTemplate>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

Nesting Wrappanel into DataGrid

I am trying to nest a WrapPanel inside a DataGrid cell. What am I missing?
This is used to display sports team information.
A Team has a TeamName, a Coach, a Roster of Players where each player has a FullName.
More technically speaking, the Roster property is a ObservableCollection where PlayerViewModel has FullName property.
<DataGrid ItemsSource="{Binding Teams}">
<DataGrid.Columns>
<DataGridTextColumn Header="Team Name" Binding="{Binding TeamName}" />
<DataGridTextColumn Header="Coach" Binding="{Binding Coach}" />
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<WrapPanel DataContext="{Binding Roster}">
<Label Content="{Binding FullName}">
</WrapPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
I figured it out. This worked.
<DataGridTemplateColumn Width="150">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<WrapPanel DataContext="{Binding Roster}">
<Label HorizontalAlignment="Center" Content="{Binding Path=FirstName}" />
</WrapPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

Cannot edit cells of my DataGrid WPF Framework 4.5

My ObservableCollection has three items, and the rows are consistently shown in the datagrid.
I cannot turn into edit mode a single cell of my DataGrid. I tried click, click-click, double-click, F2,…, but the whole row stay selected. How can I let the user edit the datagrid.
I found similar datagrid edit-questions in other posts but no-one solved my problem. Here is the code (WPF NetFramework 4.5). Pursposely, only the first column is non-editable (readonly).
<DataGrid Name="myDataGrid" Grid.Row="2" AutoGenerateColumns="False" ItemsSource="{Binding}" IsReadOnly="False">
<DataGrid.Columns>
<DataGridTemplateColumn Header="name" IsReadOnly="True" Width="200" >
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Formulation" Width="100" IsReadOnly="False">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding FormulationStr}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<TextBlock Text="{Binding FormulationStr}" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="volume Diff" Width="100" IsReadOnly="False">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding volumeDiff}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<TextBlock Text="{Binding volumeDiff}" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
You have placed TextBlock in cell template as well as in cell editing template. That's why you are not noticing any change on pressing F2 and double-clicking the cell since no matter what it will always be TextBlock which you can't edit.
Either placed TextBox in your CellEditingTemplate like this -
<DataGridTemplateColumn Header="Formulation" Width="100" IsReadOnly="False">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding FormulationStr}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<TextBox Text="{Binding FormulationStr}" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
Or either simply use the DataGridTextColumn in place of DataGridTemplateColumn which internally provides the support what are you trying to achive by the above code -
<DataGridTextColumn Header="Formulation" Width="100" IsReadOnly="False" Binding="{Binding FormulationStr}" />

Create Common DataGridTemplateColumn in WPF

I need to create a common DataGridTemplateColumn, so that I can use it across my application with different objects and properties.
here is some sample code, I use in my project
<DataGridTemplateColumn Width="100*">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Age}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<TextBox Text="{Binding Path=Age}"/>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
I need a generic version of the code so that I can place the DataTemplate in app.xaml and reference it in my code
You can't template DataGridTemplateColumn directly. But fortunately you can use global templates for cells. Take a look at example:
App.xaml
<Application.Resources>
<DataTemplate x:Key="CellEdintingTemplate">
<TextBox Text="{Binding Path=Age}" />
</DataTemplate>
<DataTemplate x:Key="CellTemplate">
<TextBlock Text="{Binding Path=Age}" />
</DataTemplate>
</Application.Resources>
Using
<DataGrid>
<DataGrid.Columns>
<DataGridTemplateColumn
CellEditingTemplate="{StaticResource CellEdintingTemplate}"
CellTemplate="{StaticResource CellTemplate}" />
</DataGrid.Columns>
</DataGrid>

Resources