Wpf apply datagrid templates - wpf

In my page I have a datagrid on which I would apply different templates, for example a template based on my custom type, so each custom have different number of columns.
Basically I would do this (pseudo code):
<Datagrid>
<DataGridTemplates>
<DataGridTemplate name="A">
<DataGridTemplate.Columns>
<DataGridTextColumn Header="Firstname" Binding="{Binding Firstname}" />
<DataGridTextColumn Header="Name" Lastname="{Binding Lastname}" />
</DataGridTemplate.Columns>
</DataGridTemplates
<DataGridTemplate name="B">
<DataGridTemplate.Columns>
<DataGridTextColumn Header="Firstname" Binding="{Binding Firstname}" />
<DataGridTextColumn Header="Name" Lastname="{Binding Lastname}" />
<DataGridTextColumn Header="Address" Lastname="{Binding Address}" />
</DataGridTemplate.Columns>
</DataGridTemplates
<DataGridTemplates>
</Datagrid>
So based on some conditions, I would want to use DataGridTemplate A instead of B. How can I achieve a task like this?

Ali Beyit I think he wants to to choose the templates, not the grid to display. I think he has just one datagrid and several templates. I dunno if you can choose a template with triggers

Related

How do I have DataGrid Templates and change them as needed

I am busy with a basic function where the user is presented with a ListBox that contains the tables within a database. To the right of the ListBox is a DataGrid which displays the fields in the table. This means that the columns will change every time another table is selected and is where my problem lies. I am aware of the auto column generation feature but since I would like to provide my own column names I need to do it manually. I have read about the event that you can handle to change the names when auto column generation is active but since I am using MVVM I would like to steer clear of using the code behind file for event handling.
The idea I have is to rather create a couple of templates and then use a trigger inside the DataGrid to select the correct column layout. This is what I have at the moment.
The templates:
<UserControl.Resources>
<DataTemplate x:Key="template_measurement">
<DataGrid>
<DataGrid.Columns>
<DataGridTextColumn Header="ID" Binding="{Binding id}"/>
<DataGridTextColumn Header="Name" Binding="{Binding name}"/>
<DataGridTextColumn Header="Latitude" Binding="{Binding source_latitude}"/>
<DataGridTextColumn Header="Longitude" Binding="{Binding source_longitude}"/>
</DataGrid.Columns>
</DataGrid>
</DataTemplate>
<DataTemplate x:Key="template_realestate">
<DataGrid>
<DataGrid.Columns>
<DataGridTextColumn Header="ID" Binding="{Binding id}"/>
<DataGridTextColumn Header="Name" Binding="{Binding name}"/>
</DataGrid.Columns>
</DataGrid>
</DataTemplate>
</UserControl.Resources>
The DataGrid:
<DataGrid AutoGenerateColumns="False"
Name="grdData"
HorizontalAlignment="Left"
Margin="10,10,0,0"
Grid.Row="2"
VerticalAlignment="Top"
Height="200"
Width="500"
ItemsSource="{Binding Path=SelectedTable}">
<DataGrid.Triggers>
<Trigger Property="{Binding Path=SelectedTableName}" Value="measurement">
<Setter Property="DataGrid" Value="{StaticResource template_measurement}"/>
</Trigger>
</DataGrid.Triggers>
</DataGrid>
The above doesn't work and I suspect that it might be seriously wrong but hopefully shows what I am attempting to achieve. The SelectedTableName property is a string that holds the name of the currently selected table.
How do I get the DataGrid to use one of the templates that I have provided based on the SelectedTableName value?
Well I think half of your approach is correct half is not,
instead of havind data templates and then set it to grid you can have ContentControl and then set its content template like you are trying right now.

Linq to list, then to DataGrid

I have an Account(accountID, accountName, transactionCount) and I want, using LINQ insert all rows into List and display that list on DataGrid.
I load rows into List:
List<Account> accounts = dataContext.Accounts.ToList();
Now I don't know how to insert that into DataGrid, I predefined DataGrid columns. I can imagine that I'm missing some maping.
Also, maybe I can directly load all table rows into DataGrid (but with predefined columns). But I think that I will need this List option for joining tables.
Here is the XAML code of DataGrid. I tried to use Gamesh tip, but grid remains blank:
<DataGrid AutoGenerateColumns="False" Height="200" HorizontalAlignment="Left" Margin="164,25,0,0" Name="dataGridAccounts" VerticalAlignment="Top" Width="299">
<DataGrid.Columns>
<DataGridTextColumn Header="Account ID" />
<DataGridTextColumn Header="Account Name" />
<DataGridTextColumn Header="Transactions Count" />
</DataGrid.Columns>
</DataGrid>
Try the add binding as below.
<DataGrid AutoGenerateColumns="False" Height="200" HorizontalAlignment="Left" Margin="164,25,0,0" Name="dataGridAccounts" VerticalAlignment="Top" Width="299">
<DataGrid.Columns>
<DataGridTextColumn Header="Account ID" Binding="{Binding accountID}" />
<DataGridTextColumn Header="Account Name" Binding="{Binding accountName}" />
<DataGridTextColumn Header="Transactions Count" Binding="{Binding transactionCount}" />
</DataGrid.Columns>
</DataGrid>

How To Bind Data From Database to DataGrid In Wpf?

how to Bind data to DATA GRID In WPF ,I get Following Error "Set connectionId threw an exception". On DataGrid
I have Following Code.
<DataGridTextColumn Header="RollNo" Width="50" Binding="{Binding RollNo}"></DataGridTextColumn>
<DataGridTextColumn Header="Name" Width="100" Binding="{Binding Name}"></DataGridTextColumn>
<DataGridTextColumn Header="City" Width="100" Binding="{Binding City}"></DataGridTextColumn>
<DataGridTextColumn Header="PinCode" Width="75" Binding="{Binding Pincode}"></DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
</GroupBox>
There is no need to store your data in Session. You can use a plain string variable for this.
Anyway, if you want to send HTML email you should mark it: message.IsBodyHtml = true;

need help optimizing performance of a datagrid

I have a DataGrid with 3000 rows and 12 columns. DataGrid is readonly and contains only text fields. Those text fields contain data that doesn't exceed 50 characters. This is the DataGrid's XAML:
<DataGrid SelectionUnit="Cell" Grid.Column="1" AutoGenerateColumns="False" CanUserAddRows="False" CanUserDeleteRows="False" ScrollViewer.CanContentScroll="False" DataGrid:SelectedItem.AutoScroll="True" SelectedItem="{Binding Path=SelectedItem}" ItemsSource="{Binding Path=GridData}" Name="DataGrid1" >
<DataGrid.Columns>
<DataGridTextColumn Header="{x:Static props:Resources.Header1}" IsReadOnly="True" Binding="{Binding Path=SomeBindingPath}"/>
<DataGridTextColumn Header="{x:Static props:Resources.Header2}" IsReadOnly="True" Binding="{Binding Path=SomeBindingPath}"/>
<DataGridTextColumn Header="{x:Static props:Resources.Header3}" IsReadOnly="True" Binding="{Binding Path=SomeBindingPath}"/>
<DataGridTextColumn Header="{x:Static props:Resources.Header4}" IsReadOnly="True" Binding="{Binding Path=SomeBindingPath}"/>
<DataGridTextColumn Header="{x:Static props:Resources.Header5}" IsReadOnly="True" Binding="{Binding Path=SomeBindingPath}"/>
<DataGridTextColumn Header="{x:Static props:Resources.Header6}" IsReadOnly="True" Binding="{Binding Path=SomeBindingPath}" Visibility="{Binding Path=DataContext.ColumnVisibility, RelativeSource={x:Static RelativeSource.Self}}"/>
<DataGridTextColumn Header="{x:Static props:Resources.Header7}" IsReadOnly="True" Binding="{Binding Path=SomeBindingPath}"/>
<DataGridTextColumn Header="{x:Static props:Resources.Header8}" IsReadOnly="True" Binding="{Binding Path=SomeBindingPath}"/>
<DataGridTextColumn Header="{x:Static props:Resources.Header9}" IsReadOnly="True" Binding="{Binding Path=SomeBindingPath}"/>
<DataGridTextColumn Header="{x:Static props:Resources.Header10}" IsReadOnly="True" Binding="{Binding Path=SomeBindingPath}"/>
<DataGridTextColumn Header="{x:Static props:Resources.Header11}" IsReadOnly="True" Binding="{Binding Path=SomeBindingPath}"/>
<DataGridTextColumn Header="{x:Static props:Resources.Header12}" IsReadOnly="True" Binding="{Binding Path=SomeBindingPath}"/>
</DataGrid.Columns>
</DataGrid>
It takes 30 seconds and 300 MB of RAM to load the DataGrid. This is way too much. How do I fix it?
I thought that DataGrids have virtualization configured by default, but it doesn't seem so. I've tried adding VirtualizingStackPanel.IsVirtualizing="False" to DataGrid and DataGridTextColumn elements, but this didn't help.
As I've already said, there is only 3000 rows of data, so I don't see any point in implementing data virtualization. Or maybe I should?
I've also tried adding following XAML:
<DataGrid.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel/>
</ItemsPanelTemplate>
</DataGrid.ItemsPanel>
If it is read only then go with GridView ListView. And use TextBlock (not TextBox). DataGrid is a heavy weight control and with it comes a lot of overhead. ListView has good UI virtualization (use recycling and deferrred scrolling). You may need to go to Data Virtualization but I would start with optimizing the UI. I have some very big list in ListView with great performance.
Had a comment on GridView and a proposed edit to remove it. The real worker is the ListView. The GridView is just the formatting. You list 12 columns and to get columns to allign GridView is clean and easy. ListView with a template (and no GridView) is an option - just not the option I would use in this case.
I would suggest looking into Data Virtualization.
There is a good CodeProject article about it here and a good blog post explaining some of the ins and outs here.
Essentially, you only cache chunks of the data (manageable amounts) and the rest is placeholders in the itemscontrol. As you scroll more items into view, items on the end are loaded, and items that you previously have viewed can either be retained or discarded as you like. It all depends on your circumstances.
It really depends on your data how you will implement, so I wont yet attempt an example.
CanContentScroll should be set to true. If I set it to false I am forcing virtualization to be turned off.

Simple WPF 4 Question: DataGrid of List of Objects is showing no records

This is driving me nuts. I have a datagrid in WPF that is not populating with records at runtime.
Here is the XAML. I've done this before in Silverlight although I am a newbie and can't quite figure out what is missing.
<DataGrid AutoGenerateColumns="True" Height="335" HorizontalAlignment="Left" Name="DataGrid1" VerticalAlignment="Top" Width="753">
<DataGrid.Columns>
<DataGridTextColumn Header="Date" Width="175" Binding="{Binding DateTimePosted}"/>
<DataGridTextColumn Header="Name" Width="275" Binding="{Binding Name}"/>
<DataGridTextColumn Header="Debit" Width="100" Binding="{Binding DebitAmout}" />
<DataGridTextColumn Header="Credit" Width="100" Binding="{Binding CreditAmount}" />
<DataGridTextColumn Header="Balance" Width="100" Binding="{Binding Balance}" />
</DataGrid.Columns>
</DataGrid>
In code in the loading event I do the following.
DataGrid1.DataContext = Facade.GetTransactions
this returns a list of TransactionItems (custom object) that have public properties matching the fields I am binding in the datagrid XAML.
I've checked and ensured 74 records are being returned.
The grid is still showing up as blank. I'm going bonkers as I can't find an example that is showing me what I can do to correct this.
WPF 4.
I've tried AutoGenerateColumns = True and = False... no diff
Advice
I think you need to use the ItemsSource property, not the DataContext property.

Resources