Extended WPF ToolkitからDateTimePicker
のコントロールテンプレートを書き換えようとしています。ので、今既存のパーツを含むRestyleコントロールテンプレート
[TemplatePart(Name = PART_Calendar, Type = typeof(Calendar))]
[TemplatePart(Name = PART_TimeUpDown, Type = typeof(TimePicker))]
public class DateTimePicker : DateTimePickerBase
{
private const string PART_Calendar = "PART_Calendar";
private const string PART_TimeUpDown = "PART_TimeUpDown";
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
if(_calendar != null)
_calendar.SelectedDatesChanged -= Calendar_SelectedDatesChanged;
_calendar = GetTemplateChild(PART_Calendar) as Calendar;
if(_calendar != null)
{
_calendar.SelectedDatesChanged += Calendar_SelectedDatesChanged;
_calendar.SelectedDate = Value ?? null;
_calendar.DisplayDate = Value ?? this.ContextNow;
this.SetBlackOutDates();
}
_timePicker = GetTemplateChild(PART_TimeUpDown) as TimePicker;
}
}
<Style TargetType="{x:Type local:DateTimePicker}">
...
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:DateTimePicker}">
...
<StackPanel>
<Calendar x:Name="PART_Calendar" BorderThickness="0" />
<local:TimePicker x:Name="PART_TimeUpDown" ... />
</StackPanel>
...
</ControlTemplate>
</Setter.Value>
<Setter>
</Style>
:
ここでは、元のコードの関連部分です:ここでは、それはどのように見えるかの写真がありますDateTimePicker
は、特定のイベントでカレンダー部分のプロパティを調整するために、コードのロジックのかなりの部分を持っています。私はホイールを再構成することは嫌です。理想的には、私は単純に、このようなコントロールのスタイルを変更できるようにしたいと思います:
CustomStyles.xaml
<Style x:Key="MetroDateTimePicker" TargetType="{x:Type xctk:DateTimePicker}">
<Setter Property="Foreground" Value="{DynamicResource TextBrush}"/>
<Setter Property="Background" Value="{DynamicResource ControlBackgroundBrush}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="BorderBrush" Value="{DynamicResource TextBoxBorderBrush}"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="FontFamily" Value="{DynamicResource ContentFontFamily}"/>
<Setter Property="FontSize" Value="{DynamicResource ContentFontSize}"/>
<Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/>
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type xctk:DateTimePicker}">
<Grid>
<Border x:Name="Base"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
<Grid Margin="5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<xctk:ButtonSpinner x:Name="PART_Spinner"
Grid.Column="0"
BorderThickness="0"
IsTabStop="False"
Background="Transparent"
Style="{StaticResource MetroButtonSpinner}"
AllowSpin="{TemplateBinding AllowSpin}"
ShowButtonSpinner="{TemplateBinding ShowButtonSpinner}">
<xctk:WatermarkTextBox x:Name="PART_TextBox"
BorderThickness="0"
Background="Transparent"
FontFamily="{TemplateBinding FontFamily}"
FontSize="{TemplateBinding FontSize}"
FontStretch="{TemplateBinding FontStretch}"
FontStyle="{TemplateBinding FontStyle}"
FontWeight="{TemplateBinding FontWeight}"
Foreground="{TemplateBinding Foreground}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
IsReadOnly="{Binding IsReadOnly, RelativeSource={RelativeSource TemplatedParent}}"
MinWidth="20"
AcceptsReturn="False"
Padding="0"
TextAlignment="{TemplateBinding TextAlignment}"
TextWrapping="NoWrap"
Text="{Binding Text, RelativeSource={RelativeSource TemplatedParent}}"
TabIndex="{TemplateBinding TabIndex}"
Watermark="{TemplateBinding Watermark}"
WatermarkTemplate="{TemplateBinding WatermarkTemplate}" />
</xctk:ButtonSpinner>
<ToggleButton x:Name="_calendarToggleButton"
Background="{TemplateBinding Background}"
Grid.Column="1"
IsChecked="{Binding IsOpen, RelativeSource={RelativeSource TemplatedParent}}"
Style="{DynamicResource ChromelessButtonStyle}"
Foreground="{TemplateBinding Foreground}"
IsTabStop="False">
<Path Fill="{TemplateBinding Foreground}"
Data="..."
Stretch="Uniform">
<Path.Width>
<Binding RelativeSource="{RelativeSource TemplatedParent}"
Path="FontSize"
Converter="{x:Static shared:FontSizeOffsetConverter.Instance}">
<Binding.ConverterParameter>
<sys:Double>4</sys:Double>
</Binding.ConverterParameter>
</Binding>
</Path.Width>
<Path.Height>
<Binding RelativeSource="{RelativeSource TemplatedParent}"
Path="FontSize"
Converter="{x:Static shared:FontSizeOffsetConverter.Instance}">
<Binding.ConverterParameter>
<sys:Double>4</sys:Double>
</Binding.ConverterParameter>
</Binding>
</Path.Height>
</Path>
</ToggleButton>
</Grid>
<Popup x:Name="PART_Popup"
AllowsTransparency="True"
IsOpen="{Binding IsChecked, ElementName=_calendarToggleButton}"
PopupAnimation="{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}"
StaysOpen="False">
<Border Padding="3"
Background="{DynamicResource WhiteBrush}"
BorderBrush="{DynamicResource ComboBoxPopupBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Effect="{DynamicResource DropShadowBrush}">
<StackPanel>
<Calendar x:Name="Part_Calendar"
BorderThickness="0"
MinWidth="115"
DisplayDateStart="{Binding Minimum, RelativeSource={RelativeSource TemplatedParent}}"
DisplayDateEnd="{Binding Maximum, RelativeSource={RelativeSource TemplatedParent}}"
IsTodayHighlighted="False"/>
<xctk:TimePicker x:Name="PART_TimeUpDown"
Style="{StaticResource MetroTimePicker}"
Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"
Foreground="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"
Format="{TemplateBinding TimeFormat}"
FormatString="{TemplateBinding TimeFormatString}"
Value="{Binding Value, RelativeSource={RelativeSource TemplatedParent}}"
Minimum="{Binding Minimum, RelativeSource={RelativeSource TemplatedParent}}"
Maximum="{Binding Maximum, RelativeSource={RelativeSource TemplatedParent}}"
ClipValueToMinMax="{Binding ClipValueToMinMax, RelativeSource={RelativeSource TemplatedParent}}"
IsUndoEnabled="{Binding IsUndoEnabled, RelativeSource={RelativeSource TemplatedParent}}"
AllowSpin="{TemplateBinding TimePickerAllowSpin}"
ShowButtonSpinner="{TemplateBinding TimePickerShowButtonSpinner}"
Watermark="{TemplateBinding TimeWatermark}"
WatermarkTemplate="{TemplateBinding TimeWatermarkTemplate}"
Visibility="{TemplateBinding TimePickerVisibility}"
Margin="3 0 3 3"/>
</StackPanel>
</Border>
</Popup>
</Grid>
<ControlTemplate.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsReadOnly, RelativeSource={RelativeSource Self}}" Value="False" />
<Condition Binding="{Binding AllowTextInput, RelativeSource={RelativeSource Self}}" Value="False" />
</MultiDataTrigger.Conditions>
<Setter Property="IsReadOnly" Value="True" TargetName="PART_TextBox" />
</MultiDataTrigger>
<DataTrigger Binding="{Binding IsReadOnly, RelativeSource={RelativeSource Self}}" Value="True">
<Setter Property="IsReadOnly" Value="True" TargetName="PART_TextBox" />
</DataTrigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
注:これは私が変更しただけのものではありません。実際には私が省略した2つのスタイルがあります(MetroTimePicker
とMetroButtonSpinner
)。すべてが大部分のためによく見えます、それは正しく動作しません。コード内にブレークポイントを設定すると(ApplyTemplate
が呼び出された後)、プライベート_calendar
フィールドがnullであることがわかります。を直接呼び出すと、nullが返されます(これは[ウォッチ]または[イミディエイト]ウィンドウで可能です)。
カスタムスタイルを適用すると、テンプレートの名前付き要素を取得できなくなったようです。私は何かが欠けているはずです。なぜなら、そこにあるすべての名前付き部分(適切な型を持っていた)があれば、ほぼすべてのコントロールテンプレートを適用できると思ったからです。だから私の質問は、WPFコントロールにカスタムテンプレートを適用し、名前付きパーツに関連付けられたロジックが期待通りに機能し続けるようにする方法です。
私は、私はこれを見てきましたどのくらい知っているダブルとトリプルチェックをすべての名前を、何とか私はこの愚かな小さなタイプミスを見たことがないしていませんこれはかなり特殊なシナリオです。演繹的な推論の全体的な順序を助けるかもしれないいくつかの例外情報/エラーの特定のものを持っていないかぎり、このことを具体的に調べる必要がありますか? –
@ChrisW。はい、申し訳ありませんが、私は今この問題の周りに脳をぶち壊しています。完全なスタイルはかなり大きく(実際には3つのスタイルが含まれているので)、私はここでそれにも関わりたくありません。しかし、私の中核的な問題は、 '_calendar'フィールドがヌルで、私のスタイルの全体的な構造が実際に元のものと非常に似ていることを考えると、何らかの理由が考えられません。例外はありません。 –
...あなたはPART_ *を使っていると確信していますか?すべてが役に立つかもしれないことを見て、コントロールテンプレートを上書きすることから少し微妙な詳細があると考えてください。 –