Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/266.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用WPF Datagrid生成一年的考勤详细信息-最好的方法是什么?_C#_Wpf - Fatal编程技术网

C# 使用WPF Datagrid生成一年的考勤详细信息-最好的方法是什么?

C# 使用WPF Datagrid生成一年的考勤详细信息-最好的方法是什么?,c#,wpf,C#,Wpf,我正在使用下面的代码获取使用wpf DataGrid的员工的年度考勤仪表板详细信息。实际问题是将数据与wpf DataGrid列绑定非常混乱。我希望动态生成所有网格列并将数据绑定到其中。我的要求是在列标题中显示日期,并从每行开始显示数据职位应以每月的第一天为准。为了更清晰,请查看附件中的图片 我是否应该为每个专栏生成模型,比如FirstSunday,FirstMonday,同样地,这些直到每周的第五个星期六,以绑定专栏,或者是否有任何其他方法可以轻松地进行绑定。 任何帮助都将不胜感激 下面的代

我正在使用下面的代码获取使用wpf DataGrid的员工的年度考勤仪表板详细信息。实际问题是将数据与wpf DataGrid列绑定非常混乱。我希望动态生成所有网格列并将数据绑定到其中。我的要求是在列标题中显示日期,并从每行开始显示数据职位应以每月的第一天为准。为了更清晰,请查看附件中的图片

我是否应该为每个专栏生成模型,比如FirstSunday,FirstMonday,同样地,这些直到每周的第五个星期六,以绑定专栏,或者是否有任何其他方法可以轻松地进行绑定。 任何帮助都将不胜感激

下面的代码用于生成包含假日详细信息的所有日期和月份名称

   public class DashboardDateDetails
    {
        public bool IsHoliday { get; set; }
        public string DayName { get; set; }
        public string ShortDate { get; set; }
        public DateTime Date { get; set; }
        public string MonthWithYear { get; set; }
        public string ReasonForHoliday { get; set; }
    }
//输入参数HolidaysList将保存一年中的假期列表。此方法将返回所选年份的日期和日期,以及从1月1日到12月31日的假期详细信息

private List<DashboardDateDetails> GetDashBoardData(List<KeyValuePair<string,DateTime>> HolidaysList)
{
    List<DashboardDateDetails> MonthList = new List<DashboardDateDetails>();
    int CurrentYear = DateTime.Now.Year;
    DateTime FirstDateOfYear = new DateTime(CurrentYear,01,01);            
    System.Globalization.CultureInfo Culture = new System.Globalization.CultureInfo("en-US");
    string[] DayNames = Culture.DateTimeFormat.AbbreviatedDayNames;
    string[] MonthNames = Culture.DateTimeFormat.MonthNames;
    string FirstDayNameOfYear = DayNames[(int)FirstDateOfYear.DayOfWeek];
    for (int MonthCount = 1; MonthCount <= 12; MonthCount++)
    {
        int NumberOfDaysInMonth = DateTime.DaysInMonth(CurrentYear, MonthCount);
        for (int DayCount = 1; DayCount <= NumberOfDaysInMonth; DayCount++)
        {                    
            DashboardDateDetails DateDetails = new DashboardDateDetails();
            DateTime CurrentDate = new DateTime(CurrentYear, MonthCount, DayCount);
            DateDetails.DayName = DayNames[(int)CurrentDate.DayOfWeek];
            DateDetails.Date = CurrentDate;
            DateDetails.ShortDate = CurrentDate.ToShortDateString();
            DateDetails.MonthWithYear = MonthNames[(int)CurrentDate.Month - 1];
            if (HolidaysList != null && HolidaysList.Any())
            {
                var HolidayDate = HolidaysList.Where(a => a.Value.ToShortDateString() == CurrentDate.ToShortDateString());
                DateDetails.IsHoliday = HolidayDate != null && HolidayDate.Any();
                DateDetails.ReasonForHoliday = HolidayDate != null && HolidayDate.Count() > 0 ? HolidayDate.First().Key : string.Empty;
            }
            MonthList.Add(DateDetails);
        }
    }
    return MonthList;
}
private List GetDashBoardData(列出假期列表)
{
列表月份列表=新列表();
int CurrentYear=DateTime.Now.Year;
DateTime FirstDateOfYear=新的日期时间(当前年份,01,01);
System.Globalization.CultureInfo Culture=新的System.Globalization.CultureInfo(“en-US”);
string[]DayNames=Culture.DateTimeFormat.缩写DayNames;
字符串[]MonthNames=Culture.DateTimeFormat.MonthNames;
字符串FirstDayNameOfYear=DayNames[(int)FirstDateOfYear.DayOfWeek];
for(int MonthCount=1;MonthCount 0?HolidayDate.First()。键:string.Empty;
}
月列表。添加(日期详细信息);
}
}
返回月份列表;
}

您好,下面的实现与您想要的并不完全相同,但我希望它能给您一个想法。我没有谈风格,所有这些都只是想给您一个逻辑概念

xaml

自定义类型

public enum HolidayType
{
没有一个
萨托森,
公众假期,
限制性假日
}
公课日
{
公共整数?数字日{get;set;}
公共HolidayType HolidayType{get;set;}
}
公共类DashboardDateDetails
{
公共字符串MonthName{get;set;}
公共列表天数{get;set;}
}
视图模型

公共类视图模型
{
公共视图模型()
{
DashboardDates=新列表();
GenerateCalendar();
}
//这将绑定到ItemsSource
公共列表仪表板日期{get;set;}
//假设这些是限制性假日
列表限制假日=新列表{
新日期时间(2014年2月1日),
新日期时间(2014年3月5日),
新日期时间(2014年4月15日),
新日期时间(2014年6月2日),
新日期时间(2014年8月15日),
新日期时间(2014年11月25日),
新日期时间(2014,12,24)
};
//假设这些是公共假日
列出公共假日=新列表{
新日期时间(2014年2月1日),
新日期时间(2014年3月15日),
新日期时间(2014年4月19日),
新日期时间(2014,6,20),
新日期时间(2014年8月11日),
新日期时间(2014年11月12日),
新日期时间(2014年12月25日)
};
void GenerateCalendar()
{
//Lop治疗12个月
对于(整数月份=1;月份s.月份==月份);
//本月公众假期
var publicHolidays=publicHolidays.Where(s=>s.Month==Month);
//DashboardDateDetails的实例
DashboardDateDetails=新DashboardDateDetails
{
MonthName=CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(月),
Days=新的一天[40]。ToList()//创建一个容量为40的数组
};
对于(int j=1;j s.Day==指数))
day.HolidayType=HolidayType.RestrictedHoliday;
//这是公共假日吗
if(公共假日.任何(s=>s.日==指数))
day.HolidayType=HolidayType.PublicHoliday;
详细信息。天[索引]=天;
}
仪表板日期。添加(详细信息);
}
}
}
输出


我希望这将帮助您给出一个想法。

感谢您宝贵的解决方案。我在动态绑定方面很努力。现在有了一个想法。索引值需要更新为Index=j+5,而不是Index=j-1,以显示从周日开始的月份。太好了!!!!!
 <DataGrid AutoGenerateColumns="False" x:Name="dataGrid" IsReadOnly="True" ItemsSource="{Binding DashboardDates}"/>
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        //Creat datagrid columns.Can also be done in xaml. but for short i have done in .cs 
        CreateCoulmns();
        DataContext = new ViewModel();
    }

    void CreateCoulmns()
    {
        var converter = new BackGroundConverter();
        for (int i = -1; i < 35; i++)
        {
            DataGridTextColumn dataGridTextColumn = new DataGridTextColumn();

            if (i == -1)
            {
                dataGridTextColumn.Header = "Month / Day";
                dataGridTextColumn.Binding = new Binding("MonthName");
            }
            else
            {
                switch (i % 7)
                {
                    case 0: dataGridTextColumn.Header = "Mo"; break;
                    case 1: dataGridTextColumn.Header = "Tu"; break;
                    case 2: dataGridTextColumn.Header = "We"; break;
                    case 3: dataGridTextColumn.Header = "Th"; break;
                    case 4: dataGridTextColumn.Header = "Fr"; break;
                    case 5: dataGridTextColumn.Header = "Sa"; break;
                    case 6: dataGridTextColumn.Header = "Su"; break;
                }
                dataGridTextColumn.Binding = new Binding(string.Format("Days[{0}].NumericDay", i));

                //Set BackGround property in style and use converter to set background according to HolidayType
                dataGridTextColumn.CellStyle = new Style(typeof(DataGridCell));
                dataGridTextColumn.CellStyle.Setters.Add(
                    new Setter
                    {
                        Property = DataGridCell.BackgroundProperty,
                        Value = new Binding(string.Format("Days[{0}]", i)) { Converter = converter }

                    });
            }
            dataGrid.Columns.Add(dataGridTextColumn);

        }
    }
}
public class BackGroundConverter : IValueConverter
{

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var day = value as Day;
        if (day != null)
        {
            //Dont use else if Like Saturday can be a restricted holiday so gray needs to be overridden by red.
            if (day.HolidayType == HolidayType.SatOrSun)
                return new SolidColorBrush(Colors.Gray);
            if (day.HolidayType == HolidayType.RestrictedHoliday)
                return new SolidColorBrush(Colors.Red);
            if (day.HolidayType == HolidayType.PublicHoilday)
                return new SolidColorBrush(Colors.Blue);
        }
        return null;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
public enum HolidayType
{
    None,
    SatOrSun,
    PublicHoilday,
    RestrictedHoliday
}

public class Day
{
    public int? NumericDay { get; set; }

    public HolidayType HolidayType { get; set; }
}

public class DashboardDateDetails
{
    public string MonthName { get; set; }

    public List<Day> Days { get; set; }
}
public class ViewModel
{
    public ViewModel()
    {
        DashboardDates = new List<DashboardDateDetails>();
        GenerateCalendar();
    }
    //This will be binded to ItemsSource
    public List<DashboardDateDetails> DashboardDates { get; set; }

    //Suppose these are Restricted Holidays
    List<DateTime> RestrictedHolidays = new List<DateTime>{
        new DateTime(2014,2,1),
        new DateTime(2014,3,5),
        new DateTime(2014,4,15),
        new DateTime(2014,6,2),
        new DateTime(2014,8,15),
        new DateTime(2014,11,25),
        new DateTime(2014,12,24)
    };

    //Suppose these are Public Holidays
    List<DateTime> PublicHolidays = new List<DateTime>{
        new DateTime(2014,2,1),
        new DateTime(2014,3,15),
        new DateTime(2014,4,19),
        new DateTime(2014,6,20),
        new DateTime(2014,8,11),
        new DateTime(2014,11,12),
        new DateTime(2014,12,25)
    };

    void GenerateCalendar()
    {
        //Lop for 12 months
        for (int month = 1; month <= 12; month++)
        {
            //firstdate for month.This will help to get the first day of month
            var firstdate = new DateTime(2014, month, 1);

            //Get the first date index
            int firstDateIndex = (int)firstdate.DayOfWeek;
            //In DayOfWeek enum first day is Sunday but we want Monday so decrement the index
            firstDateIndex--;

            //Restricted holidays for this month
            var restrictedHolidays = RestrictedHolidays.Where(s => s.Month == month);

            //Public holidays for this month
            var publicHolidays = PublicHolidays.Where(s => s.Month == month);

            //Instance of DashboardDateDetails
            DashboardDateDetails details = new DashboardDateDetails
            {
                MonthName = CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(month),
                Days = new Day[40].ToList()  //Create an array of capacity 40
            };

            for (int j = 1; j <= DateTime.DaysInMonth(2014, month); j++)
            {
                int index = 0;

                if (firstDateIndex < 0)
                    index = j - 1;
                else
                    index = j + firstDateIndex - 1;

                var day = new Day { NumericDay = j };
                //is sat or sun
                if (((index % 7) == 6) || ((index % 7) == 5))
                    day.HolidayType = HolidayType.SatOrSun;
                //is restricted holiday
                if (restrictedHolidays.Any(s => s.Day == index))
                    day.HolidayType = HolidayType.RestrictedHoliday;
                //is public holiday
                if (publicHolidays.Any(s => s.Day == index))
                    day.HolidayType = HolidayType.PublicHoilday;

                details.Days[index] = day;
            }

            DashboardDates.Add(details);
        }
    }

}