Я смоделировал подход, отличный от того, что вы предлагали. Это упрощено, и я сделал пару предположений, но давайте попробуем.
Вместо использования сетки и сопоставления дней в сетке давайте воспользуемся WrapPanel и просто поместим в нее дочерних элементов, каждый из которых представляет день.
В свой App.xaml.cs вы можете поместить код, который создаст объект Day
.
public class Day
{
public DateTime Date { get; set; }
public List<Appointment> Appointments { get; set; }
}
public partial class App : Application
{
protected override void OnActivated(EventArgs e)
{
base.OnActivated(e);
var daysCollection = new List<Day>();
for (int i = 1; i <= 30; i++)
{
daysCollection.Add(new Day
{
// arbitrary sample data
Date = new DateTime(2011, 04, i),
Appointments =
new List<Appointment>
{
new Appointment
{
Date = new DateTime(2011, 04, i),
Description = "Some descriptive text"
}
}
});
}
this.Properties.Add("DaysCollection", daysCollection );
}
}
Теперь у нас есть набор дней. Назначения не важны для этой части выборки.
Теперь мы создаем простой календарь UserControl и привязываем его к CalendarViewModel.
<UserControl x:Class="DaysCalendarBinding.Views.Calendar"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
Height="210" Width="210">
<WrapPanel x:Name="wrapPanel" Orientation="Horizontal"
ItemHeight="30" ItemWidth="30"
Loaded="wrapPanel_Loaded">
</WrapPanel>
</UserControl>
ViewModel
public class CalendarViewModel
{
public CalendarViewModel()
{
}
public CalendarViewModel(IEnumerable<Day> inputDays)
{
// determine first day of the month passed in
var firstDate =
(from day in inputDays
orderby day.Date.Day
select day.Date).First();
var todayIs = firstDate.DayOfWeek;
var valueOfToday = (int) todayIs;
// create this many blank day children
DaysInMonth = new List<Day>();
for (int i = valueOfToday; i > 0; i--)
{
// the start of some cheeze. I know. It's a sample.
DaysInMonth.Add(new Day { Date = new DateTime(1,1,1) });
}
// add the rest ofthe days in to the collection
foreach(var day in inputDays)
{
DaysInMonth.Add(day);
}
}
public List<Day> DaysInMonth { get; private set; }
}
С обработчиком событий, когда загружается wrapPanel
private void wrapPanel_Loaded(object sender, RoutedEventArgs e)
{
foreach (var day in ((CalendarViewModel)DataContext).DaysInMonth)
{
wrapPanel.Children.Add(
new DayView {
DataContext = new DayViewModel(day) });
}
}
Теперь мы создаем элементы управления DayViewModel и DayView, которые мы создаем и добавляем в WrapPanel.
<UserControl x:Class="DaysCalendarBinding.Views.DayView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="30" d:DesignWidth="30">
<Border BorderBrush="Black" BorderThickness="1">
<StackPanel Height="30" Width="30" Background="AliceBlue">
<TextBlock FontSize="7" Text="{Binding DayDate}"/>
</StackPanel>
</Border> </UserControl>
ViewModel
public class DayViewModel
{
private Day innerDay;
public DayViewModel() {}
public DayViewModel(Day day)
{
innerDay = day;
}
public string DayDate
{
get
{
// I know this is a cheesy approach. It's a sample. :)
if (innerDay.Date.Year != 1)
// this only intended to demonstrate some content
return innerDay.Date.DayOfWeek.ToString().Remove(3) +
" " + innerDay.Date.Day;
return string.Empty;
}
}
}
Теперь, наконец, наше главное окно, в которое мы добавляем элемент управления календарем, добавляем CalendarViewModel и, надеюсь, когда мы нажимаем F5, он отображается для вас. :)
<Window x:Class="DaysCalendarBinding.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Views="clr-namespace:DaysCalendarBinding.Views" Title="Calendar Demo" Height="350" Width="525">
<Grid>
<Views:Calendar x:Name="calendarControl"></Views:Calendar>
</Grid>
</Window>
Код программной части в MainWindow.xaml.cs
protected override void OnActivated(EventArgs e)
{
base.OnActivated(e);
calendarControl.DataContext =
new CalendarViewModel((IEnumerable<Day>)Application
.Current
.Properties["DaysCollection"]);
}
Возможно, я сделал пару ошибок, перенеся это сюда из своего решения. Но я надеюсь, что это передает идею. Для меня это выглядит так.
Календарь марта
![Скриншот мартовского календаря](https://i.stack.imgur.com/eDFG6.png)
Апрель календарь
![Скриншот апрельского календаря](https://i.stack.imgur.com/BcTle.png)
Теперь пришло время собрать все это вместе, чтобы это работало на вас. Это просто демонстрирует технику. Представить значимый контроль не должно быть так сложно.
Ваше здоровье.
person
Dave White
schedule
25.03.2011