使用动态过滤在 WinForms 网格中计算高于每周工作时间阈值的员工百分比

Calculating Percentage of Employees Above Weekly Hours Threshold in WinForms Grid with Dynamic Filtering

提问人:William Sewell 提问时间:11/16/2023 最后编辑:William Sewell 更新时间:11/17/2023 访问量:33

问:

我有一个 WinForms 项目,其中包含一个在网格中显示员工数据的报表。我正在尝试计算每周平均工作时间超过文本框中输入的阈值的员工百分比。当未对网格应用筛选时,计算工作正常,但当我根据 Agency 或 EmployeeType 筛选网格时,百分比不正确。

下面是相关代码的片段:

// Code to get data and calculate percentage
private HMReportsController ReportController = new HMReportsController(cGlobal.ConnectionString);
private const string ReportHeader = "Average Employee Hours Report";
private int RowCount = 0;
private double HourThreshold = 0;
private double AboveAverageCount = 0;
private double AboveAveragePercentage;

private void button_GetData_Click(object sender, EventArgs e)
{
    Cursor.Current = Cursors.WaitCursor;
    try
    {
        averageEmployeeHourModelBindingSource.DataSource = ReportController.GetAverageEmployeeHours(dateEdit_DateFrom.DateTime, dateEdit_DateTo.DateTime);                
    }
    catch (Exception Ex)
    {
        MessageBox.Show(Ex.Message);
    }
    Cursor.Current = Cursors.Default;
}

private void buttom_Calculate_Click(object sender, EventArgs e)
{
    try
    {
        // Get the threshold value from the numericTextBox_hours
        double threshold = (double)numbericTextBox_Hours.GetNumericValue();

        // Calculate the count of people with WeeklyAverage above the threshold
        AboveAverageCount = averageEmployeeHourModelBindingSource
            .Cast<AverageEmployeeHourModel>()
            .Count(item => item.WeeklyAverage.HasValue && item.WeeklyAverage.Value > threshold);

        // Calculate the total count of items in the grid
        RowCount = averageEmployeeHourModelBindingSource.Count;

        // Calculate the percentage
        AboveAveragePercentage = (RowCount > 0) ? (AboveAverageCount / RowCount) * 100 : 0;

        // Display the percentage in label_Percentage
        label_Percentage.Text = $"Percentage above threshold: {AboveAveragePercentage:F2}%";
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

模型:

public class AverageEmployeeHourModel
{
    public int? PayrollID { get; set; }
    public double? WeeklyAverage { get; set; }
    public string EmployeeName { get; set; }
    public string Agency { get; set; }
    public int? NumberOfWeeks { get; set; }
    public string EmployeeType { get; set; }
}

当我在 Agency 或 EmployeeType 上筛选网格时,会出现此问题,并且计算变得不准确。

我试图通过捕获列筛选器更改来处理此问题,但我观察到,如果我筛选然后取消筛选代理,则它不会重新添加到绑定源中。

如何确保百分比的计算准确,即使基于“代理”或“员工类型”对网格应用动态筛选?任何建议或代码示例将不胜感激。谢谢!

C# WinForms 开发快报

评论

0赞 jarlh 11/16/2023
这真的与SQL语言有关吗?我在上面没有看到 SQL。你期待一个SQL的答案吗?
0赞 Shahram Alemzadeh 11/17/2023
这似乎是一个devexpress网格控件。然后,您可以简单地获取 from 属性和 from ,或者使用 gridcontrol 的内置摘要选项。Filtered RowCount gridview.rowcountRowCountgridview.datasource.count

答:

0赞 William Sewell 11/17/2023 #1

我通过使用新模型和过滤器布尔值解决了我的问题:

private BindingList<AverageEmployeeHourModel> filteredEmployeeHourModels = new BindingList<AverageEmployeeHourModel>();

// Flag to indicate whether filters are applied
private bool filtersApplied = false;

每次更改列的筛选器时,都会写入新模型:

private void gridView1_ColumnFilterChanged(object sender, EventArgs e)
{
    UpdateFilteredData();
}

private void UpdateFilteredData()
{
    // Clear the existing filtered data
    filteredEmployeeHourModels.Clear();

    // Iterate through the filtered rows and add them to the new model
    for (int i = 0; i < gridView1.RowCount; i++)
    {
        if (gridView1.IsDataRow(i) && !gridView1.IsGroupRow(i) && !gridView1.IsFilterRow(i))
        {
            AverageEmployeeHourModel rowData = gridView1.GetRow(i) as AverageEmployeeHourModel;
            if (rowData != null)
            {
                filteredEmployeeHourModels.Add(rowData);
            }
        }
    }

    // Update the filtersApplied flag so that the calculation uses the filtered data
    filtersApplied = filteredEmployeeHourModels.Count > 0;
}

然后,如果应用了筛选器,请使用新模型,如果没有,请使用原始绑定源:

private void buttom_Calculate_Click(object sender, EventArgs e)
{
    try
    {
        if (filtersApplied)
        {
            // Get the threshold value from numericTextBox_Hours
            double threshold = Convert.ToDouble(numericTextBox_Hours.Text);

            // Count the number of employees whose average weekly hours are over the threshold
            int aboveThresholdCount = filteredEmployeeHourModels.Count(emp => emp.WeeklyAverage > threshold);

            // Calculate the percentage
            double percentage = (double)aboveThresholdCount / filteredEmployeeHourModels.Count * 100;

            // Display the percentage in label_Percentage
            label_Percentage.Text = $"{percentage:F2}%";
        }
        else
        {
            // Get the threshold value from numericTextBox_Hours
            double threshold = Convert.ToDouble(numericTextBox_Hours.Text);

            // Count the number of employees whose average weekly hours are over the threshold
            int aboveThresholdCount = ((IEnumerable<AverageEmployeeHourModel>)averageEmployeeHourModelBindingSource.DataSource).Count(emp => emp.WeeklyAverage > threshold);

            // Calculate the percentage
            double percentage = ((IEnumerable<AverageEmployeeHourModel>)averageEmployeeHourModelBindingSource.DataSource).Count() > 0 ? (double)aboveThresholdCount / ((IEnumerable<AverageEmployeeHourModel>)averageEmployeeHourModelBindingSource.DataSource).Count() * 100 : 0;

            // Display the percentage in label_Percentage
            label_Percentage.Text = $"{percentage:F2}%";
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}