如何在CalendarItemTemplate中更改DayTitleTemplate的DataTemplate

时间:2011-05-11 01:25:13

标签: wpf templates xaml calendar

当我尝试更改日历 DayTitleTemplate 的默认 DataTemplate 时,如果根元素不是Textblock,则应用程序崩溃。

有谁知道如何避免崩溃?

以下是用于演示目的的模板的简化版本。 (Kaxaml ready)

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
    <Calendar>
        <Calendar.CalendarItemStyle>
            <Style TargetType="CalendarItem">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="CalendarItem">
                            <ControlTemplate.Resources>
                <!-- ___________________________________________________________________ -->
                <!-- This is the default Data template -->
                                <DataTemplate x:Key="{ComponentResourceKey ResourceId=DayTitleTemplate, TypeInTargetAssembly={x:Type CalendarItem}}">
                                    <TextBlock HorizontalAlignment="Center" Margin="0,6" VerticalAlignment="Center" FontFamily="Verdana" FontSize="9.5" FontWeight="Bold" Foreground="#FF333333" Text="{Binding}"/>
                                </DataTemplate>
                <!-- ___________________________________________________________________ -->
                <!-- This is a modified Data template, using this template instead of the Default, makes the XAML crash. -->
                <!--<DataTemplate x:Key="{ComponentResourceKey ResourceId=DayTitleTemplate, TypeInTargetAssembly={x:Type CalendarItem}}">
                  <Grid>
                      <Rectangle Stroke="Brown" StrokeThickness="0.5"/>
                      <TextBlock Foreground="#FF333333" FontWeight="Bold" FontSize="9.5" FontFamily="Verdana" HorizontalAlignment="Center" Text="{Binding}" VerticalAlignment="Center"/>
                  </Grid>
              </DataTemplate>-->
                <!-- ___________________________________________________________________ -->
                            </ControlTemplate.Resources>
                            <Grid x:Name="PART_Root">
                                <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="1">
                                    <Border BorderBrush="White" BorderThickness="2" CornerRadius="1">
                                        <Grid>
                                            <Grid.ColumnDefinitions>
                                                <ColumnDefinition Width="Auto"/>
                                                <ColumnDefinition Width="Auto"/>
                                                <ColumnDefinition Width="Auto"/>
                                            </Grid.ColumnDefinitions>
                                            <Grid.RowDefinitions>
                                                <RowDefinition Height="Auto"/>
                                                <RowDefinition Height="*"/>
                                            </Grid.RowDefinitions>
                                            <Button x:Name="PART_PreviousButton" Width="28" Height="20" Grid.Column="0" Grid.Row="0" HorizontalAlignment="Left" Focusable="False">
                                            </Button>
                                            <Button x:Name="PART_HeaderButton" Grid.Column="1" Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center" Focusable="False" FontSize="10.5" FontWeight="Bold">
                                            </Button>
                                            <Button x:Name="PART_NextButton" Width="28" Height="20" Grid.Column="2" Grid.Row="0" HorizontalAlignment="Right" Focusable="False">
                                            </Button>
                                            <Grid x:Name="PART_MonthView" Grid.ColumnSpan="3" Grid.Row="1" HorizontalAlignment="Center" Margin="6,-1,6,6" Visibility="Visible">
                                                <Grid.ColumnDefinitions>
                                                    <ColumnDefinition Width="Auto"/>
                                                    <ColumnDefinition Width="Auto"/>
                                                    <ColumnDefinition Width="Auto"/>
                                                    <ColumnDefinition Width="Auto"/>
                                                    <ColumnDefinition Width="Auto"/>
                                                    <ColumnDefinition Width="Auto"/>
                                                    <ColumnDefinition Width="Auto"/>
                                                </Grid.ColumnDefinitions>
                                                <Grid.RowDefinitions>
                                                    <RowDefinition Height="*"/>
                                                    <RowDefinition Height="*"/>
                                                    <RowDefinition Height="*"/>
                                                    <RowDefinition Height="*"/>
                                                    <RowDefinition Height="*"/>
                                                    <RowDefinition Height="*"/>
                                                    <RowDefinition Height="*"/>
                                                </Grid.RowDefinitions>
                                            </Grid>
                                            <Grid x:Name="PART_YearView" Grid.ColumnSpan="3" Grid.Row="1" HorizontalAlignment="Center" Margin="6,-3,7,6" Visibility="Hidden">
                                                <Grid.ColumnDefinitions>
                                                    <ColumnDefinition Width="Auto"/>
                                                    <ColumnDefinition Width="Auto"/>
                                                    <ColumnDefinition Width="Auto"/>
                                                    <ColumnDefinition Width="Auto"/>
                                                </Grid.ColumnDefinitions>
                                                <Grid.RowDefinitions>
                                                    <RowDefinition Height="Auto"/>
                                                    <RowDefinition Height="Auto"/>
                                                    <RowDefinition Height="Auto"/>
                                                </Grid.RowDefinitions>
                                            </Grid>
                                        </Grid>
                                    </Border>
                                </Border>
                            </Grid>
                            <ControlTemplate.Triggers>
                                <DataTrigger Binding="{Binding DisplayMode, RelativeSource={RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type Calendar}}}" Value="Year">
                                    <Setter TargetName="PART_MonthView" Property="Visibility" Value="Hidden"/>
                                    <Setter TargetName="PART_YearView" Property="Visibility" Value="Visible"/>
                                </DataTrigger>
                                <DataTrigger Binding="{Binding DisplayMode, RelativeSource={RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type Calendar}}}" Value="Decade">
                                    <Setter TargetName="PART_MonthView" Property="Visibility" Value="Hidden"/>
                                    <Setter TargetName="PART_YearView" Property="Visibility" Value="Visible"/>
                                </DataTrigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </Calendar.CalendarItemStyle>
    </Calendar>
</Grid> 
</Page>

这是我得到的StackTrace(抱歉我的系统是日语,这是正常的NullReferenceException)。 我只是将xaml粘贴到一个全新的WPF应用程序项目中。我没有使用任何自动化或其他任何东西。

System.NullReferenceException はハンドルされませんでした。
  Message=オブジェクト参照がオブジェクト インスタンスに設定されていません。
  Source=PresentationCore
  StackTrace:
       場所 System.Windows.Automation.Peers.AutomationPeer.EnsureChildren()
       場所 System.Windows.Automation.Peers.AutomationPeer.UpdateChildrenInternal(Int32 invalidateLimit)
       場所 System.Windows.Automation.Peers.AutomationPeer.UpdateChildren()
       場所 System.Windows.Automation.Peers.AutomationPeer.UpdateSubtree()
       場所 System.Windows.Automation.Peers.AutomationPeer.UpdateSubtree()
       場所 System.Windows.ContextLayoutManager.fireAutomationEvents()
       場所 System.Windows.ContextLayoutManager.UpdateLayout()
       場所 System.Windows.UIElement.UpdateLayout()
       場所 System.Windows.Interop.HwndSource.Process_WM_SIZE(UIElement rootUIElement, IntPtr hwnd, WindowMessage msg, IntPtr wParam, IntPtr lParam)
       場所 System.Windows.Interop.HwndSource.LayoutFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
       場所 MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
       場所 MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
       場所 System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
       場所 MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
       場所 System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
       場所 MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
       場所 MS.Win32.UnsafeNativeMethods.ShowWindow(HandleRef hWnd, Int32 nCmdShow)
       場所 System.Windows.Window.ShowHelper(Object booleanBox)
       場所 System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
       場所 MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
       場所 System.Windows.Threading.DispatcherOperation.InvokeImpl()
       場所 System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)
       場所 System.Threading.ExecutionContext.runTryCode(Object userData)
       場所 System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
       場所 System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
       場所 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
       場所 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       場所 System.Windows.Threading.DispatcherOperation.Invoke()
       場所 System.Windows.Threading.Dispatcher.ProcessQueue()
       場所 System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
       場所 MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
       場所 MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
       場所 System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
       場所 MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
       場所 System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
       場所 MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
       場所 MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
       場所 System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
       場所 System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
       場所 System.Windows.Threading.Dispatcher.Run()
       場所 System.Windows.Application.RunDispatcher(Object ignore)
       場所 System.Windows.Application.RunInternal(Window window)
       場所 System.Windows.Application.Run(Window window)
       場所 System.Windows.Application.Run()
  InnerException: 

1 个答案:

答案 0 :(得分:2)

我遇到了类似的问题,以下帖子帮助了我:http://social.msdn.microsoft.com/Forums/ar/wpf/thread/0ee9954d-0df5-4d61-8dc9-eb50c7a5be99

在你的情况下,你会改变:

x:Key="{ComponentResourceKey ResourceId=DayTitleTemplate, TypeInTargetAssembly={x:Type CalendarItem}}"

x:Key="{x:Static CalendarItem.DayTitleTemplateResourceKey}"