我使用下面的代码来获取使用wpf DataGrid的员工年度明智的出勤仪表板详细信息。实际问题是将数据与wpf datagrid列绑定非常困惑。我想动态生成所有网格列并绑定将数据放入其中。我的要求是在列标题中显示天数,每行数据的起始位置应该基于每月的第一天。找到附加的图像以便更清晰。
我应该为FirstSunday,FirstMonday这样的每一列生成Model,直到星期六的第五个星期六来绑定列,还是有其他方法可以轻松完成。 任何帮助都将受到高度赞赏。
下面用于生成带有假日详细信息的所有日期和月份名称的代码
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;
}
答案 0 :(得分:3)
您好以下的实现并不完全相同,但我希望它会给您一个想法。我没有继续风格,只是想让您了解逻辑。
XAML
<DataGrid AutoGenerateColumns="False" x:Name="dataGrid" IsReadOnly="True" ItemsSource="{Binding DashboardDates}"/>
xaml.cs
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);
}
}
}
输出
![]()
我希望这会帮助你提出一个主意。