2016-04-13 17 views
2

DateTimePicker denetim şablonunu Extended WPF Toolkit'dan yeniden başlatmaya çalışıyorum. çünkü ŞimdiMevcut parçalarla Restyle denetim şablonu

DateTimePicker.cs

[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; 
    } 
} 

Generic.xaml

<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> 

:
Style Comparison

İşte orijinal kod ilgili kısmı var: Burada nasıl görünmesi gerektiği bir resmiDateTimePicker, takvim bölümünün belirli olaylar üzerindeki özelliklerini ayarlamak için arkadaki kodda oldukça iyi bir mantık içeriyor, tekerleği yeniden icat etmekten nefret ediyorum. İdeal olarak, ben sadece böyle kontrolünü restyle edebilmek istiyorum:

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> 

Not: Bu ben değiştim tek şey değildir; aslında iki tane daha fazla stil var (MetroTimePicker ve MetroButtonSpinner). Her şey çoğu için iyi görünüyor, doğru davranmıyor. Kodumda bir kesme noktası belirlediğimde (ApplyTemplate çağrıldıktan sonra), özel _calendar alanının boş olduğunu görebilirim. Doğrudan myPicker.GetTemplateChild("PART_Calendar") numaralı çağrı da null değerini döndürür (bu, İzle veya Komut penceresinden mümkündür).

Görünüşe göre, özel bir stil uygulandığında şablondaki adlandırılmış öğeleri almayı başaramadı. Bir şeyi özlemeliyim, çünkü neredeyse tüm kontrol şablonlarını nerede uygulayabildiğimi (ve uygun türlere sahip olduğu sürece) uygulayabileceğimi düşündüm. Benim sorum, bir WPF kontrolüne nasıl özel bir şablon uygulayabilirim ve adlandırılmış bölümleriyle ilişkili herhangi bir mantığın beklendiği gibi çalışmaya devam etmesini nasıl sağlayabilirim?

+0

Bu, oldukça özel bir senaryo. Özellikle sorun gidermek için tümdengelimli akıl yürütme sırasına yardımcı olabilecek bir özel istisna bilgi/hatası aldığınız sürece bu şeyleri kazmaya gerek duyar mıydınız? –

+0

@ChrisW. Evet üzgünüm, bir süredir beynimi bu problemin etrafında sardım. Tam stil oldukça büyüktür (ve aslında 3 farklı stile sahiptir) bu yüzden burada fazla yer almak istemiyorum. Ancak, asıl problemin '_calendar' alanının boş olması ve benim tarzımın genel yapısının aslında orijinaline oldukça benzer olduğu düşünüldüğünde herhangi bir sebep olabileceğini düşünmüyorum. İstisna yoktur. –

+0

... ve tüm PART_ * s cihazlarını kullandığınızdan emin misiniz? Herşeyin işe yarayacağını görmek, kontrol şablonunun üzerine yazmaktan biraz nüans detayı bahse girer. –

cevap

0

Tamam, ben bir aptalım. Ben bu baktım ne kadar biliyor ikili ve her ismi üç kere kontrol ettim, ama nedense ben bu aptal küçük yazım hatası görmedim yoktur:

<Calendar x:Name="Part_Calendar" … /> 

olmalıydı:

<Calendar x:Name="PART_Calendar" … />