Hello, I make my calendar with additional chips, but still at the stage of implementing the basic functionality I ran into a problem - I can not understand how to fill in the "Panel of days of the week", well, the one that says "Monday", "Tuesday", etc. , with the amendment on the first day of the week user. Indeed, in some countries, the week does not start on Monday, but on Sunday.

Here is what I tried:

private void LoadWeekPanel() { for (int i = 0; i < WeekPanel.ColumnDefinitions.Count; i++) { TextBlock tb = new TextBlock() { Text = ((DayOfWeek)i + (int)FirstDayOfWeek).ToString(), HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center }; WeekPanel.Children.Add(tb); Grid.SetColumn(tb, i); } } //WeekPanel - это Grid //FirstDayOfWeek - это CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek //DayOfWeek - это перечисление в пространстве имён System, описывающее дни недели 

As a result, I got the following result: enter image description here

I understand that the counter in the loop went beyond the limits of the enumeration, and thus this seven was added to the last TextBlock . But I can't figure out how to fix it.

  • one
    Do you know that you are “spoiling” WPF ? He does not like when elements are added from the code. I remember you wrote something like one of your answers: “If you took WPF, then you need to know about data binding in and out.” ... Learn and implement Binding, otherwise you won't get away! - EvgeniyZ
  • @EvgeniyZ, this calendar is a user control. Where necessary, I defined the dependency properties and bind. Apparently, you do not like this when elements from code are added to WPF projects, while WPF itself is quite tolerant of this. - Arthur Edgarov
  • @EvgeniyZ, if you know how to solve my problem using data binding, I’ll be happy to read your answer. - Arthur Edgarov
  • Well so you need a cycle not by the columns of the grid, but by the number of days in a week. - Andrei NOP
  • @AndreyNOP, columns 7, is a constant. If I understand you correctly :) - Arthur Edgarov

1 answer 1

How to get the days of the week:

  • First, we will create a certain method for determining the start date of the week:

     public static DateTime FirstDayOfWeek(DateTime date) { var culture = new CultureInfo("en"); DayOfWeek firstDay = culture.DateTimeFormat.FirstDayOfWeek; int offset = firstDay - date.DayOfWeek; DateTime fdowDate = date.AddDays(offset); return fdowDate; } 

    Here you can see that I brought the culture for clarity and take FirstDayOfWeek from it (the value that starts the week (Sunday or Monday)). Here you can specify for yourself where to start the week by writing the value in firstDat , or in culture indicate the current ( CurrentCulture ) culture of the user. Logically, everything is simple, I think, it is not worth explaining.

  • Next, we can make a list of the days of the week:

     var startDate = FirstDayOfWeek(DateTime.Now); var weeks = Enumerable .Range(0, 7) .Select(x => startDate.AddDays(x).DayOfWeek.ToString()); 

    It's also quite simple here, we define the beginning of the week using our method, then using LINQ we get 7 dates from our start to the end of the week and take the day of the week from them (well, we translate for example in string ). Everything, at the output we will receive all the days of the week, the first will be the one that is accepted in the culture or we will indicate personally.

Binding:

What you are doing now is a perversion of the poor WPF . Create a simple binding:

  • In the MainWindow class, we will create the property MyCollection , type the type ObservableCollection<string> :

     public ObservableCollection<string> MyCollection { get; set; } 
  • Next, after InitializeComponent(); specify the DataContext :

     InitializeComponent(); DataContext = this; 
  • After the DataContext for example, let's fill our collection with all previously received days of weeks:

     MyCollection = new ObservableCollection<string>(weeks); 
  • Now XAML , here I personally would use the usual ListBox (if you just need to make clickable days of the week):

     <ListBox ItemsSource="{Binding MyCollection}" ScrollViewer.HorizontalScrollBarVisibility="Disabled"> <ListBox.ItemsPanel> <ItemsPanelTemplate> <WrapPanel IsItemsHost="True" /> </ItemsPanelTemplate> </ListBox.ItemsPanel> </ListBox> 

    I will explain that here. We bind the ListBox element to our collection using an ItemSource . Next, we disable horizontal scrolling. To the ListBox itself, we rewrite the design of ItemsPanel , specifying the host for our elements as a WrapPanel (you can also replace it with a StackPanel for example, specifying Orientation="Horizontal" ). By such actions, we redefined the position of the elements in the ListBox and now they are arranged horizontally.

Well, that's all, we now have all the days of the week, with offset and conveniently placed in the ListBox . It remains only to add the processing of the selected element and decorate everything with design.

Result:

img