How to fix an endless rendering / measure loop with WPF? - c#

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?

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>

C# WPF DataGrid virtualization is slow

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.

Formatting rows in a datagrid to look blank

Essentially, I am using a datagrid in WPF. If there is a row that contains no data, I want it to be a blank row and I want it to display as below:
However I am having real trouble trying to achieve this. I can do it by creating separate datagrids and splitting the data into each with a converter but it becomes very messy and makes the code hard to maintain.
I can also do it by leaving the row blank which looks as below:
However that does not look quite how I would like. Any help is appreciated and thanks in advance.
Code for the datagrid:
<DataGrid Width="265" RowHeight="11.5" CanUserAddRows="False" ItemsSource="{Binding Coupon.SelectionAreas[0].SelectionRows
,Converter={StaticResource DateTimeToSplitDataGridConverter}
,ConverterParameter='Table13Bet'}" AutoGenerateColumns="False" Background="Transparent" RowBackground="Transparent" HeadersVisibility="None" BorderBrush="LightGray" BorderThickness="1,0,1,0" AlternatingRowBackground="{x:Null}" GridLinesVisibility="Horizontal" IsReadOnly="True" SelectionMode="Single" >
<DataGrid.Columns>
<DataGridTemplateColumn Width="27">
<DataGridTemplateColumn.CellTemplate >
<DataTemplate DataType="r:SelectionRow">
<TextBlock Text="{Binding ExpectedOffDate,StringFormat='HH:mm'}" VerticalAlignment="Top" FontFamily="Arial Narrow" FontSize="7.8" HorizontalAlignment="Center" Foreground="{Binding Path=ColourForeground, Converter={StaticResource HexToForegroundColourConverter}}"
Background="{Binding Path=ColourBackground, Converter={StaticResource HexToBackgroundColourConverter}}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Width="27" >
<DataGridTemplateColumn.CellTemplate>
<DataTemplate DataType="r:SelectionRow">
<TextBlock Text="{Binding SelectionHome.Odd, Converter={StaticResource ChangeZeroToOneOddsToTbcConverter}}" FontFamily="Arial Narrow" VerticalAlignment="Top" FontSize="7.8" HorizontalAlignment="Center" Background="{Binding Path=ColourBackground, Converter={StaticResource HexToBackgroundColourConverter}}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Width="80" >
<DataGridTemplateColumn.CellTemplate>
<DataTemplate DataType="r:SelectionRow">
<TextBlock Text="{Binding SelectionHome.DisplayName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" FontFamily="Arial Narrow" FontSize="7.8" HorizontalAlignment="Left" Background="{Binding Path=ColourBackground, Converter={StaticResource HexToBackgroundColourConverter}}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Width="24">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate DataType="r:SelectionRow">
<TextBlock Text="{Binding SelectionDraw.Odd, Converter={StaticResource ChangeZeroToOneOddsToTbcConverter}}" VerticalAlignment="Top" FontFamily="Arial Narrow" FontSize="7.8" HorizontalAlignment="Center" Background="{Binding Path=ColourBackground, Converter={StaticResource HexToBackgroundColourConverter}}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Width="80" >
<DataGridTemplateColumn.CellTemplate>
<DataTemplate DataType="r:SelectionRow">
<TextBlock Text="{Binding SelectionAway.DisplayName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" FontFamily="Arial Narrow" FontSize="7.8" HorizontalAlignment="Right" Background="{Binding Path=ColourBackground, Converter={StaticResource HexToBackgroundColourConverter}}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Width="25" >
<DataGridTemplateColumn.CellTemplate>
<DataTemplate DataType="r:SelectionRow">
<TextBlock Text="{Binding SelectionAway.Odd, Converter={StaticResource ChangeZeroToOneOddsToTbcConverter}}" VerticalAlignment="Top" FontFamily="Arial Narrow" FontSize="7.8" HorizontalAlignment="Center" Background="{Binding Path=ColourBackground, Converter={StaticResource HexToBackgroundColourConverter}}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
it is possible to display empty RowDetails under certain rows
<DataGrid>
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<Grid Height="20"/>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Setter Property="DetailsVisibility"
Value="{Binding Path=ShowEmptyRow,
Converter={StaticResource BoolToVisible}}"/>
</Style>
</DataGrid.RowStyle>
<DataGrid>
ShowEmptyRow is some bool property which indicates that there should be an empty space under current DataGridRow

Can i make UpDown Column at DataGrid?

Can i make UpDown Column at DataGrid?
I have simple DataGrid:
<DataGrid Grid.Row="0" Grid.Column="0">
<DataGrid.Columns>
<DataGridTextColumn Header="Name"> </DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
And i want to make UpDown column. Can i do that?
Thank you!
P.S. i mean something like numericUpDown counter. :up: [1], down: [0].
I think you can do something like
<DataGrid>
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=AttrName}" Height="25" Width="150" HorizontalAlignment="Left" VerticalAlignment="Top" />
<TextBlock Text="{Binding Path=AttrDisplayLabel}" Height="25" Width="Auto" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="10,0,0,0" />
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox Height="25"
ItemsSource="{Binding Source={StaticResource cvsAttributes}}"
SelectedValuePath="AttributeID"
IsSynchronizedWithCurrentItem="False"
SelectionChanged="Selector_OnSelectionChanged"
SelectedValue="{Binding Path=AttributeId, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
<ComboBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</ComboBox.ItemsPanel>
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
....
Just replace combo with your updown/spinner control. The celltemplate is your display... the celledittemplate is your edit control...(updown...etc...)
If you mean NumericUpDown column
you can have a template column and add NumericUpDown Control to the template
Look Here for creating custom numeric updown control or simply use one provided with WPFToolkit !!
Find Codeples for Toolkit Here

Update Datagrid cell according to other cells when hit Enter

I'm using Galasoft's EventToCommand as code below to update Line Total cell after user inserts price and quantity.
Please, help me find the appropriate way to make the Line Total changes when I insert the price, quantity and hit Enter. I tried InputBindings, but unfortunately didn't work.
Here is the Datagrid XAML from my View:
<DataGrid IsReadOnly="False" x:Name="_StockCardItems" ItemsSource="{Binding InvoiceDetailsList, Mode=TwoWay}" SelectedItem="{Binding SelectedItem}" CanUserDeleteRows="True" CanUserAddRows="False">
<i:Interaction.Triggers>
<i:EventTrigger EventName="CurrentCellChanged">
<gs:EventToCommand PassEventArgsToCommand="True" Command="{Binding CurrentCellChangedCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<DataGrid.InputBindings>
<KeyBinding Key="Enter" Command="{Binding CurrentCellChangedCommand}"/>
</DataGrid.InputBindings>
<DataGrid.Columns>
<DataGridTemplateColumn Header="Désignation" Width="400" IsReadOnly="True">
<DataGridTemplateColumn.CellTemplate >
<DataTemplate>
<TextBlock Margin="10,2" HorizontalAlignment="Left" Text="{Binding Path=Items.Designation}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Quantité" Width="150" IsReadOnly="False">
<DataGridTemplateColumn.CellTemplate >
<DataTemplate>
<TextBox Margin="10,0" HorizontalAlignment="Center" GotKeyboardFocus="TextBox_GotKeyboardFocus" GotMouseCapture="TextBox_GotMouseCapture" IsReadOnly="False" Text="{Binding Path=Quantity, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged, Converter={StaticResource RemoveDoubleZero}}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="PU" Width="150" >
<DataGridTemplateColumn.CellTemplate >
<DataTemplate>
<TextBox Margin="10,0" HorizontalAlignment="Center" IsReadOnly="False" GotKeyboardFocus="TextBox_GotKeyboardFocus" GotMouseCapture="TextBox_GotMouseCapture" Text="{Binding Path=UnitePrice, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged, Converter={StaticResource RemoveDoubleZero}}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Montant HT" Width="150" >
<DataGridTemplateColumn.CellTemplate >
<DataTemplate>
<TextBlock Margin="10,2" HorizontalAlignment="Right" Text="{Binding Path=Line_Total,Mode=TwoWay,ValidatesOnExceptions=True,ValidatesOnDataErrors=True, StringFormat=n, ConverterCulture=fr-FR}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
Here is the CurrentCellChangedCommand excute method in the ViewModel (SelectedItem is an EF Entity):
private void RecalculateLineTotal()
{
if (SelectedItem != null)
SelectedItem.Line_Total = SelectedItem.Quantity * SelectedItem.UnitePrice;
}
Thanks in advance
It started to work normally after sometime. I think that was something extra prevented those Key stroks from working.

Categories

Resources