none
ShowWeekNumbers in WPF Calendar? RRS feed

  • Frage

  • Bei meinem ersten WPF-Projekt habe ich mich an den Umbau des Calendars gewagt, damit dieser Termine anzeigt.

    Was ich allerdings vermisse, sind die Kalenderwochen! Gibt es diese Option im neuen Calendar nicht mehr? Im alten MonthCalender gab es doch eine Option ShowWeekNumbers. Falls es sie doch noch gibt, wie/wo schalte ich sie ein?

    Donnerstag, 14. April 2011 09:04

Antworten

  • Nun läuft auch die Berechnung korrekt:

      Public Class KalenderWoche
        Implements IValueConverter
    
        Private dDatum As Date
        Private dErster As Date
        Dim cal As System.Windows.Controls.Calendar
        Dim row As Int16
    
        Public Function Convert(value As Object, targetType As Type, parameter As Object, culture As Globalization.CultureInfo) As Object Implements IValueConverter.Convert
    
          cal = CType(value, System.Windows.Controls.Calendar)
          row = CShort(parameter)
    
          Dim kw As Integer = getKW(cal.DisplayDate, row)
          '--------------
          Return kw
          '--------------
        End Function
    
        Public Function ConvertBack(value As Object, targetType As Type, parameter As Object, culture As Globalization.CultureInfo) As Object Implements IValueConverter.ConvertBack
          'wird nicht benötigt!
          Return CType(New Object(), Object())
        End Function
    
        Private Function getKW(ByVal dDatum As Date, ByVal row As Integer) As Integer
    
          dErster = New Date(dDatum.Year, dDatum.Month, 1)
          Dim kw As Integer = DatePart(DateInterval.WeekOfYear, dErster.AddDays((row - 1) * 7), FirstDayOfWeek.Monday, FirstWeekOfYear.FirstFourDays)
    
          If dErster.DayOfWeek = DayOfWeek.Monday Then
            kw -= 1 'erste Zeile ist dann für letzten Monat reserviert!!!
          End If
    
          '-------------
          Return kw
          '-------------
        End Function
      End Class
    • Als Antwort markiert Quidnunc1987 Donnerstag, 5. Mai 2011 11:29
    Donnerstag, 5. Mai 2011 11:29

Alle Antworten

  • Dank einiger Hilfen bin ich inzwischen wenigstens etwas weiter. Ich weiß jetzt mit Sicherheit, dass es die Option nicht gibt. Also versuche ich sie nachzubauen.

    http://www.charlespetzold.com/blog/2009/10/Adapting-the-Calendar-Control-for-Week-Numbers.html

    http://social.msdn.microsoft.com/Forums/de-DE/wpfde/thread/db65d97d-0db4-488b-95e6-96e28d678f54

     

    Mit diesen 2 Quellen bin ich jetzt schon so weit, dass die Kalenderwochen korrekt angezeigt werden. Nur beim Ändern der Woche ändert sie sich noch nicht mit.

    <!--Weeknumbers-->
                              <DockPanel Grid.Row="1" Grid.ColumnSpan="3" Grid.IsSharedSizeScope="True" Margin="0" HorizontalAlignment="Stretch">
                                <Grid Visibility="{Binding ElementName=PART_MonthView, Path=Visibility}" Background="#FFA5BFE1" Width="40">
                                  <Grid.RowDefinitions>
                                    <RowDefinition Height="Auto" SharedSizeGroup="SharedTitleHeight"/>
                                    <RowDefinition Height="Auto" SharedSizeGroup="SharedItemHeight" />
                                    <RowDefinition Height="Auto" SharedSizeGroup="SharedItemHeight" />
                                    <RowDefinition Height="Auto" SharedSizeGroup="SharedItemHeight" />
                                    <RowDefinition Height="Auto" SharedSizeGroup="SharedItemHeight" />
                                    <RowDefinition Height="Auto" SharedSizeGroup="SharedItemHeight" />
                                    <RowDefinition Height="Auto" SharedSizeGroup="SharedItemHeight" />
                                  </Grid.RowDefinitions>
    
                                  <TextBlock Grid.Row="0" Text="KW" Foreground="White" TextAlignment="Center" FontWeight="Bold" VerticalAlignment="Center" />
    
                                  <TextBlock Grid.Row="1" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="White" Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Calendar}}, Converter={StaticResource KalenderWoche}, ConverterParameter='1'}"/>
                                  <TextBlock Grid.Row="2" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="White" Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Calendar}}, Converter={StaticResource KalenderWoche}, ConverterParameter='2'}"/>
                                  <TextBlock Grid.Row="3" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="White" Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Calendar}}, Converter={StaticResource KalenderWoche}, ConverterParameter='3'}"/>
                                  <TextBlock Grid.Row="4" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="White" Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Calendar}}, Converter={StaticResource KalenderWoche}, ConverterParameter='4'}"/>
                                  <TextBlock Grid.Row="5" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="White" Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Calendar}}, Converter={StaticResource KalenderWoche}, ConverterParameter='5'}"/>
                                  <TextBlock Grid.Row="6" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="White" Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Calendar}}, Converter={StaticResource KalenderWoche}, ConverterParameter='6'}"/>
                                
                                </Grid>
                                <!--END: Weeknumbers-->
                              
                                <!-- Start: Month Content Grid -->
                                <Grid x:Name="PART_MonthView" Visibility="Visible" HorizontalAlignment="Stretch">
                                  <Grid.RowDefinitions>
                                    <RowDefinition Height="Auto" SharedSizeGroup="SharedTitleHeight"/>
                                    <RowDefinition Height="Auto" SharedSizeGroup="SharedItemHeight"/>
                                    <RowDefinition Height="Auto" SharedSizeGroup="SharedItemHeight"/>
                                    <RowDefinition Height="Auto" SharedSizeGroup="SharedItemHeight"/>
                                    <RowDefinition Height="Auto" SharedSizeGroup="SharedItemHeight"/>
                                    <RowDefinition Height="Auto" SharedSizeGroup="SharedItemHeight"/>
                                    <RowDefinition Height="*" SharedSizeGroup="SharedItemHeight"/>
                                  </Grid.RowDefinitions>
                                  <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="*"/>
                                    <ColumnDefinition Width="*"/>
                                    <ColumnDefinition Width="*"/>
                                    <ColumnDefinition Width="*"/>
                                    <ColumnDefinition Width="*"/>
                                    <ColumnDefinition Width="*"/>
                                    <ColumnDefinition Width="*"/>
                                  </Grid.ColumnDefinitions>
                                </Grid>
                              <!-- End: Month Content Grid -->
                              </DockPanel>
    

    Der Converter:

    Imports System.Windows.Data
    Imports System.Windows.Controls
    
    Namespace Kalender
      Public Class KalenderWoche
        Implements IValueConverter
    
        Private dDatum As Date
        Private dErster As Date
        Dim cal As System.Windows.Controls.Calendar
        Dim row As Int16
    
        Public Function Convert(value As Object, targetType As Type, parameter As Object, culture As Globalization.CultureInfo) As Object Implements IValueConverter.Convert
    
          cal = CType(value, System.Windows.Controls.Calendar)
          row = CShort(parameter)
    
          dDatum = cal.DisplayDate
          dErster = New Date(dDatum.Year, dDatum.Month, 1)
    
          Dim jahresAnfang As Date = New Date(dErster.Year, 1, 1)
          Dim korr2 As Int16 = 0
          If jahresAnfang.DayOfWeek = DayOfWeek.Sunday Then
            korr2 = 6
          Else
            korr2 = CShort(jahresAnfang.DayOfWeek - 1)
          End If
    
          Dim kw As Int16 = CShort((dErster.DayOfYear + korr2) / 7)
          '--------------
          Return kw + row - 1
          '--------------
        End Function
    
        Public Function ConvertBack(value As Object, targetType As Type, parameter As Object, culture As Globalization.CultureInfo) As Object Implements IValueConverter.ConvertBack
          'wird nicht benötigt!
          Return CType(New Object(), Object())
        End Function
      End Class
    End Namespace
    
    Mittwoch, 4. Mai 2011 09:07
  • Damit löse ich einen Listener beim Laden aus:

    <TextBlock x:Name="tbx1" Grid.Row="1" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="White" Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Calendar}, Converter={StaticResource KalenderWoche}, ConverterParameter='1', NotifyOnTargetUpdated=True}" Binding.TargetUpdated="Monatswechsel"/>

    Der Listener reagiert beim ersten Laden - aber nicht beim Wechseln des Monats. Also habe ich in dem obigen Listener die Textboxen weggespeichert und im Calendar1.DisplayDateChanged durchlaufen

     Private Sub Monatswechsel(sender As System.Object, e As System.Windows.Data.DataTransferEventArgs)
      Dim tb As TextBlock = CType(sender, TextBlock)
      If Not tbKW.Contains(tb) Then
       tbKW.Add(tb)
      End If
     End Sub
      For Each t As TextBlock In tbKW
       t.GetBindingExpression(TextBlock.TextProperty).UpdateTarget()
      Next
    Elegant ist das sehr wahrscheinlich nicht! Aber es funktioniert (außer dass ich einen Fehler in der Berechnung der Kalenderwochen entdeckt habe, der vermutlich mit den unterschiedlichen Indexen der Wochentage bei C und VB liegt)
    Mittwoch, 4. Mai 2011 13:07
  • Nun läuft auch die Berechnung korrekt:

      Public Class KalenderWoche
        Implements IValueConverter
    
        Private dDatum As Date
        Private dErster As Date
        Dim cal As System.Windows.Controls.Calendar
        Dim row As Int16
    
        Public Function Convert(value As Object, targetType As Type, parameter As Object, culture As Globalization.CultureInfo) As Object Implements IValueConverter.Convert
    
          cal = CType(value, System.Windows.Controls.Calendar)
          row = CShort(parameter)
    
          Dim kw As Integer = getKW(cal.DisplayDate, row)
          '--------------
          Return kw
          '--------------
        End Function
    
        Public Function ConvertBack(value As Object, targetType As Type, parameter As Object, culture As Globalization.CultureInfo) As Object Implements IValueConverter.ConvertBack
          'wird nicht benötigt!
          Return CType(New Object(), Object())
        End Function
    
        Private Function getKW(ByVal dDatum As Date, ByVal row As Integer) As Integer
    
          dErster = New Date(dDatum.Year, dDatum.Month, 1)
          Dim kw As Integer = DatePart(DateInterval.WeekOfYear, dErster.AddDays((row - 1) * 7), FirstDayOfWeek.Monday, FirstWeekOfYear.FirstFourDays)
    
          If dErster.DayOfWeek = DayOfWeek.Monday Then
            kw -= 1 'erste Zeile ist dann für letzten Monat reserviert!!!
          End If
    
          '-------------
          Return kw
          '-------------
        End Function
      End Class
    • Als Antwort markiert Quidnunc1987 Donnerstag, 5. Mai 2011 11:29
    Donnerstag, 5. Mai 2011 11:29