I have a DataGrid with 10-15 columns which can have around 100-200 rows. The datagrid is placed within a Tab control ( which is not in focus by default ).
I tried to virtualize the DataGrid but when I click the tab containing the DataGrid, the program freezes for like 4-5 seconds, and then the tab opens displaying the datagrid. After that the rows seem to scroll fast which is good, but the columns still behave slow like un-virtualized.
When I remove the code to virtualize (last 4 options in DataGrid tag), the grid displays immediately but scrolls very slow and lags.
The following is my datagrid code:
<DataGrid Name="xDataGridFieldConfig"
FrozenColumnCount ="1"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
VerticalAlignment="Stretch"
Style="{DynamicResource FieldConfigDataGridHeaderStyle}"
AutoGenerateColumns="False"
CanUserResizeColumns="False"
CanUserResizeRows="False"
CanUserReorderColumns="False"
SelectionMode="Single"
GridLinesVisibility="Horizontal"
HorizontalGridLinesBrush="#cbcaca"
HeadersVisibility="Column" ItemsSource="{Binding FieldConfigCollection}"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Visible"
VirtualizingPanel.IsVirtualizingWhenGrouping="True"
VirtualizingPanel.VirtualizationMode="Standard"
VirtualizingPanel.IsVirtualizing="True"
ScrollViewer.CanContentScroll="False">
<DataGrid.Columns>
<DataGridTextColumn Header="S No." Binding="{Binding Path=ID}" IsReadOnly="True" Width="80"/>
<!-- using template for custom checkbox -->
<DataGridTemplateColumn Header="EN" IsReadOnly="False">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<flatcheckbox:FlatCheckBox x:Name="xFlatCheckBoxFieldConfigEN" Margin="0" IsChecked="{Binding Path=Enabled, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<flatcheckbox:FlatCheckBox x:Name="xFlatCheckBoxFieldConfigEN" Margin="0" IsChecked="{Binding Path=Enabled, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Group" Width="150">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Name="xTextBlockFieldConfigGroup" Text="{Binding Path=Group, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<TextBox Name="xTextBlockFieldConfigGroup" IsEnabled="{Binding Enabled}" Text="{Binding Path=Group, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Padding="0" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
<!-- 10 similar text-only editable rows -->
</DataGrid.Columns>
</DataGrid>
Is there anything wrong I'm doing ? How to make the datagrid to be displayed immediately as soon as I open the tab.
Related
I'm debugging a code made by a former employee at the company I am working as an intern.
Turns out a DataGrid is not selecting items. Everytime I try to access DataGrid.SelectedItem it returns me null, even though one row is selected.
As you can see in this print
Follows the XAML code:
<DataGrid x:Name="SchedulesDataGrid"
Grid.Row="1"
Margin="0 10 0 0"
AlternatingRowBackground="LightSteelBlue"
CanUserReorderColumns="False"
CanUserSortColumns="False"
CanUserResizeColumns="False"
CanUserAddRows="False"
CanUserResizeRows="False"
SelectionMode="Single"
SelectionUnit="CellOrRowHeader"
AutoGenerateColumns="False"
IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding AssemblySchedules, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<DataGrid.Columns>
<DataGridTextColumn Header="Name"
Binding="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
IsReadOnly="False"
Width="200">
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="HorizontalAlignment" Value="Left"/>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<DataGridTemplateColumn Header="Type"
Width="150">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding ScheduleType, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
SelectedItem="{Binding SelectedScheduleType, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
x:Name="ScheduleTypeComboBox"
IsSynchronizedWithCurrentItem="True"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Category"
Width="150">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding Categories, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
SelectedItem="{Binding SelectedCategory, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
x:Name="ScheduleCategoryComboBox"
IsSynchronizedWithCurrentItem="True"
DisplayMemberPath="Name"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="View template"
Width="250">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding ScheduleTemplates, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
SelectedItem="{Binding SelectedScheduleTemplate, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
x:Name="ScheduleTemplateComboBox"
IsSynchronizedWithCurrentItem="True"
DisplayMemberPath="Name"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Phase"
Width="150">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding Phases, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
SelectedItem="{Binding SelectedPhase, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
x:Name="SchedulePhase"
IsSynchronizedWithCurrentItem="True"
DisplayMemberPath="Name"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
Am I missing something?
I read throughout the internet that a PropertyChanged binding is necessary but I believe it is already done the right way.
DataGrid print screen
Can it possibly be because I have to click over the Name in the row, therefore the SelectedItem is not "triggered"?
This is the way I initialized my Data Grid
<DataGrid MaxHeight="450"
CanUserAddRows="False"
CanUserDeleteRows="False"
CanUserReorderColumns="False"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto"
ItemsSource="{Binding Results}"
SelectedItem="{Binding SelectedResult}">
Then in the ViewModel I have this
private Data selectedResult;
public Data SelectedResult
{
get { return selectedResult; }
set
{
if (selectedResult != value)
{
selectedResult = value;
RaisePropertyChanged(nameof(SelectedResult));
}
}
}
Data Being the model for the DataGrid Columns
Okay, so basically I had to change some things.
Don't know why and how the selection part of my data grid stopped working. So I created another column to it and added a remove button to each row of the data grid.
To get the row I used inside the button On_Click method (sender as Button).DataContext and removing it from the data grid source list.
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>
Can we bind the image column from a different source and the other columns from the datatable?
<DataGrid x:Name="GridViewProducts" Margin="80,30,0,0"
AutoGenerateColumns="True" BorderThickness="12"
BorderBrush="PaleTurquoise" ItemsSource="{Binding}" Height="200"
Width="745" HorizontalAlignment="Center"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"
VerticalAlignment="Center" MouseEnter="GridViewProducts_MouseEnter" >
<DataGrid.Columns>
<DataGridTemplateColumn DisplayIndex="0"
x:Name="imageColumn">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Image x:Name="image_Grid_Column"
Source="{Binding ImageSource}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
I have the following XAML code implementing a data grid with DirectionalNavigation = Cycle.
<DataGrid
KeyboardNavigation.DirectionalNavigation="Cycle"
x:Name="ToolPathGridView"
VirtualizingPanel.VirtualizationMode="Recycling"
ScrollViewer.IsDeferredScrollingEnabled="True"
CanUserAddRows="False"
SelectionUnit="FullRow"
CanUserDeleteRows="False"
SelectionMode="Single"
ItemsSource="{Binding
ToolPath.ToolPath,
Mode=OneWay,
Converter={StaticResource IndexedConverter}}"
AutoGenerateColumns="False"
SelectedIndex="{Binding SelectedIndex, Mode=TwoWay}">
<DataGrid.Resources>
<SolidColorBrush
x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}"
Color="DarkGray"/>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.Header>
Id
</DataGridTemplateColumn.Header>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Index}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn>
<DataGridTemplateColumn.Header>
<StackPanel Orientation="Horizontal">
<TextBlock
Text="{Binding Source={StaticResource T9N},
Path=SwivelAxis}" />
</StackPanel>
</DataGridTemplateColumn.Header>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Label Content="{Binding Value.ToolAxes.Swivel}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn>
<DataGridTemplateColumn.Header>
<StackPanel Orientation="Horizontal">
<TextBlock
Text="{Binding Source={StaticResource T9N},
Path=ChuckAxis}" />
</StackPanel>
</DataGridTemplateColumn.Header>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Label Content="{Binding Value.ToolAxes.Chuck}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn>
<DataGridTemplateColumn.Header>
<StackPanel Orientation="Horizontal">
<TextBlock
Text="{Binding Source={StaticResource T9N},
Path=VerticalAxis}" />
</StackPanel>
</DataGridTemplateColumn.Header>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Label Content="{Binding Value.ToolAxes.Vertical}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
Using the arrow keys I can move up and down the rows.
If the last row in the data-grid is selected, as above, and the down arrow is pressed then the first row in the list should become selected. However WPF goes into an endless measure / arrange loop.
I previously had custom user controls in each of the cell templates but have removed them and replaced them with plain labels just in case my controls were behaving badly.
Does anybody have an idea if this is a bug in WPF or a problem with my usage of the data grid?
It seems an easy problem but I can't figure out.
The scenery:
In C#/WPF/MVVM, I have a DataGrid showing some data. One field (a cell of a row) is an integer value. Now I need to display a ComboBox for that cell showing "local" if the value is 0, "Network" if the value is 1 or greater. How can I bind this?
Thank you.
You should be able to use DataGridTemplateColumn Template to do this.
Below is a sample to help:
<DataGrid Grid.Row="0"
AutoGenerateColumns="False" Height="Auto"
SelectionMode="Single" ItemsSource="{Binding MyViewItemModels}"
RowDetailsVisibilityMode="Collapsed" HeadersVisibility="Column" CanUserAddRows="False"
GridLinesVisibility="None" AlternationCount="2" AlternatingRowBackground="GhostWhite" Background="White">
<DataGrid.Columns>
<DataGridTemplateColumn IsReadOnly="True" MinWidth="50" Width="70" >
<DataGridTemplateColumn.Header>
<Border Height="30">
<Label Content="My Name"/>
</Border>
</DataGridTemplateColumn.Header>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox Height="16" ItemsSource="{Binding MyItems, Mode=OneWay}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>