数据网格在滚动时表现得很奇怪

时间:2016-11-29 17:22:53

标签: c# datagrid refresh

编辑:我已经注意到问题不在第一行,但鼠标滚动后所有行都被移动。

我完全清楚这是一个棘手的问题,可能会导致我提出一个不完整或过于个人化的问题。那说我会尽可能清楚地解释它。 我有一个datagrid,由我通过例程构建。如果有必要,我可以分享。之后,数据网格通过事件进行转换:

<DataGrid Name="dtgResults" Background="Transparent" CanUserSortColumns="False" IsReadOnly="True" Foreground="Black" LoadingRow="Datagrid_LoadingRow">
    <DataGrid.Resources>
        <Style TargetType="DataGridCell">
            <EventSetter Event="DataGridCell.Loaded" Handler="DataGridCell_Load"/>
                <Setter Property="Tag" Value="{Binding RelativeSource={RelativeSource AncestorType=DataGrid}}"/>
                <Setter Property="HorizontalAlignment" Value="Right" />
        </Style>
    </DataGrid.Resources>
</DataGrid>

即:

在Datagrid_LoadingRow

int index = row.GetIndex();
if (obcMyDim[index].IsComment) <-----a matrix telling when it's a comment
    row.Foreground = new SolidColorBrush(Colors.White);
else
    row.Foreground = new SolidColorBrush(Colors.Black);

所以这只是一个着色问题,没有细胞数据变化!

在DataGridCell_Load中的

我将格式化小数位数并通过它来实现:

DataGridCell cell = sender as DataGridCell;
DataGrid parentDataGrid = (DataGrid)(cell.Tag);

int column = cell.Column.DisplayIndex;// da 0
int row = -1;
//I get the line
DependencyObject rowDO = cell as DependencyObject;
while (rowDO != null && !(rowDO is DataGridRow))
    rowDO = VisualTreeHelper.GetParent(rowDO);
if (rowDO != null)
{
    DataGridRow gridrow = (DataGridRow)rowDO;
    row = gridrow.GetIndex();
}

...

string strCellContent = ((TextBlock)cell.Content).Text;
if (strCellContent.Trim() != string.Empty)
{
    if (strCellContent.IsNumeric())<----custom function
    {
        dVal = double.Parse(strCellContent, CultureInfo.InvariantCulture);
        ((TextBlock)cell.Content).Text = dVal.ToString("0.0000");

        bool condOutOfTolerance = ...;
        //Errore
        if (column >= 5 && condOutOfTolerance)
            cell.Foreground = new SolidColorBrush(Colors.Red);
    }
}

因此,简而言之,问题是第一行在

之后表现得很奇怪

这是第一个正确的图像。 enter image description here

然后向上/向下滚动数据网格后第一行更改

enter image description here

然后再次不同

enter image description here

我觉得不知何故这是一个刷新问题,但我无法理解如何解决这个问题。

感谢您的帮助

帕特里克 ---- ---- ADD

以下是我手动填充数据网格的方法:

public void SynchronizeDtgResults(DataGrid dtg)
{
    /*-----------------------------------------------*
     * manuale generation HEADER / COLUMNS / ROWS *
     *-----------------------------------------------*/
    if (obcMyDim == null || obcMyDim.Count() == 0 || obcMyDim[0].obcItemsName == null || obcMyDim[0].obcItemsName.Count() == 0)
    {
        Serializers.Logger.WriteLog("WARNING SynchronizeDtgResults called with obcmMyDim not valid");
        return;
    }

    int numColonneFisse = 5; //Num, name, nominal, ut, ul
    int numParts = obcMyDim[0].obcItemsName.Count();//refer to the first coz are all the same
    int numTotaleColonne = numColonneFisse + numParts;
    int numTotaleRighe = obcMyDim.Count;
    string[] columnLabels = new string[numTotaleColonne];

    //1. Header Preparation
    // first 5 fixed col
    columnLabels[0] = Languages.Word(eWords.Num);
    columnLabels[1] = Languages.Word(eWords.Name);
    columnLabels[2] = Languages.Word(eWords.Nominal);
    columnLabels[3] = Languages.Word(eWords.UT);
    columnLabels[4] = Languages.Word(eWords.LT);
    // and then the names of the parts
    for (int iii = 0; iii < numParts; iii++)
        columnLabels[iii + numColonneFisse] = obcMyDim[0].obcItemsName[iii];

    //2. Clean and add header
    Application.Current.Dispatcher.Invoke((Action)(() => { dtg.Columns.Clear(); }));
    Application.Current.Dispatcher.Invoke((Action)(() => { dtg.Items.Clear(); }));

    var styleHeaderDatagrid = new Style(typeof(System.Windows.Controls.Primitives.DataGridColumnHeader));
    styleHeaderDatagrid.Setters.Add(new Setter { Property = BorderBrushProperty, Value = Brushes.Black });
    styleHeaderDatagrid.Setters.Add(new Setter { Property = BorderThicknessProperty, Value = new Thickness(1) });
    styleHeaderDatagrid.Setters.Add(new Setter { Property = ForegroundProperty, Value = Brushes.Black });
    styleHeaderDatagrid.Setters.Add(new Setter { Property = FontWeightProperty, Value = FontWeights.Bold });
    styleHeaderDatagrid.Setters.Add(new Setter { Property = MarginProperty, Value = new Thickness(2) });

    var tb = new TextBlock() { FontSize = dtg.FontSize, FontFamily = dtg.FontFamily };
    reportDimensionNameWidth = 0;
    foreach (var item in obcMyDim)
    {
        tb.Text = item.NameAxisDimension;
        double dim = GraphicExtensions.GetTextBlockSize(tb).Width;
        if (dim > reportDimensionNameWidth)
            reportDimensionNameWidth = dim + 20;
    }

    foreach (string label in columnLabels)
    {
        DataGridTextColumn column = new DataGridTextColumn();
        column.Header = label;
        column.HeaderStyle = styleHeaderDatagrid;
        column.Binding = new Binding(label.Replace(' ', '_'));

        column.Width = new DataGridLength(1, DataGridLengthUnitType.Auto);
        Application.Current.Dispatcher.Invoke((Action)(() => { dtg.Columns.Add(column); }));
    }

    //3 adding rows
    int num = 1;
    for (int riga = 0; riga < numTotaleRighe; riga++)
    {
        dynamic newRow = new ExpandoObject();

        //Adding dimension per each row
        for (int colonna = 0; colonna < numTotaleColonne; colonna++)
        {
            string strColumnHeader = columnLabels[colonna].Replace(' ', '_');
            ((IDictionary<String, Object>)newRow)[strColumnHeader] = string.Empty;
            switch (colonna)
            {
                //Here fixed lines
                case 0: if (!obcMyDim[riga].IsComment) ((IDictionary<String, Object>)newRow)[strColumnHeader] = num++; break;
                case 1: ((IDictionary<String, Object>)newRow)[strColumnHeader] = obcMyDim[riga].NameAxisDimension; break;
                case 2: if (!obcMyDim[riga].IsComment) ((IDictionary<String, Object>)newRow)[strColumnHeader] = obcMyDim[riga].Nominal; break;
                case 3: if (!obcMyDim[riga].IsComment) ((IDictionary<String, Object>)newRow)[strColumnHeader] = obcMyDim[riga].UpperTolerance; break;
                case 4: if (!obcMyDim[riga].IsComment) ((IDictionary<String, Object>)newRow)[strColumnHeader] = obcMyDim[riga].LowerTolerance; break;

                //Here all data
                default:
                    if (!obcMyDim[riga].IsComment)
                    {
                        if (colonna < numTotaleColonne)
                        {
                            if ((colonna - numColonneFisse < 0) || (colonna - numColonneFisse) > obcMyDim[riga].obcItemsMeasured.Count)
                            {
                                string str = "Wrong num column obcMyDim idx=" + (colonna - numColonneFisse) + "  obcmMyDim[" + riga + "].obcItemsMeasured.Count= " + obcMyDim[riga].obcItemsMeasured.Count;
                                MessageBox.Show(str);
                            }
                            else
                                ((IDictionary<String, Object>)newRow)[strColumnHeader] = (obcMyDim[riga].obcItemsMeasured[colonna - numColonneFisse]).ToString();
                        }
                        else
                            MessageBox.Show("DtgResult Wrong column number: " + colonna);
                    }
                    break;
            }
        }

    Serializers.Logger.WriteLog("SynchronizeDtgResults added new row num=" + riga + " name=" + obcMyDim[riga].NameAxisDimension);

    Application.Current.Dispatcher.Invoke((Action)(() => { dtg.Items.Add(newRow); }));
    }
    Serializers.Logger.WriteLog("SynchronizeDtgResults END");
}

再次感谢您的帮助!!!!

2 个答案:

答案 0 :(得分:1)

这看起来是与以下之一相关的问题。如何在数据网格中填充数据或如何处理行索引。滚动时,这会导致数据网格刷新和更新。

要测试的一些事情是关闭数据虚拟化并查看DataGridCell_Load。如果关闭数据虚拟化没有帮助。 DataGridCell_Load存在一些逻辑错误。

您能否添加任何可以转换/修改数据网格的其他代码?

最终解决方案是数据虚拟化。

答案 1 :(得分:0)

我刚刚遇到了同样的问题。滚动网格将开始发送 SelectedColorChanged 控件的 ColorPicker 事件、CellEditEndingDataGrid 事件以及 DataGridComboBoxColumn 的一些事件。关闭解决方案中提到的 EnableRowVirtualizationEnableColumnVirtualizationDataGrid 属性确实解决了问题。