2012-03-16 70 views
0

我可能完全沒有這個,但我發誓我記得在某處讀到如何做到這一點,我似乎無法找到它。作爲TimePicker自定義控件的一部分,我有一個DependencyProperty Minutes。它的數據類型爲int,因爲這是獲取增加/減少按鈕的唯一方法。問題在於1-9的分鐘數不顯示前導零。爲了規避這個問題,我添加了一個標準屬性MinuteZeros,它將Minutes的值轉換爲string並採用ToString("00")。該屬性綁定到顯示內容。現在當我點擊增加/減少按鈕時,它不會更新。我如何綁定MinutesMinuteZeros,以便它們自動更新對方?標準房地產更新以及DependencyProperty

代碼:

public class TimePicker : Control 
{ 
    public static DependencyProperty HourProperty = DependencyProperty.Register("Hour", typeof(int), typeof(TimePicker), 
     new FrameworkPropertyMetadata((int)12, new PropertyChangedCallback(OnHourChanged))); 

    public static DependencyProperty MinuteProperty = DependencyProperty.Register("Minute", typeof(int), typeof(TimePicker), 
     new FrameworkPropertyMetadata((int)00, new PropertyChangedCallback(OnMinuteChanged))); 

    public int Hour 
    { 
     get { return (int)GetValue(HourProperty); } 
     set { SetValue(HourProperty, value); } 
    } 

    public string MinuteZeros 
    { 
     get { return Minute.ToString("00"); } 
     set { value = Minute.ToString("00"); } 
    } 

    public int Minute 
    { 
     get { return (int)GetValue(MinuteProperty); } 
     set { SetValue(MinuteProperty, value); } 
    } 
    #endregion 

    #region Events 

    public override void OnApplyTemplate() 
    { 
     var upButton = GetTemplateChild("PART_IncreaseTime") as RepeatButton; 
     upButton.Click += IncreaseClick; 

     var downButton = GetTemplateChild("PART_DecreaseTime") as RepeatButton; 
     downButton.Click += DecreaseClick; 

     var hourButton = GetTemplateChild("PART_Hour") as ToggleButton; 
     hourButton.Checked += HourSelected; 

     var minuteButton = GetTemplateChild("PART_Minute") as ToggleButton; 
     minuteButton.Checked += MinuteSelected; 
    } 

    private void HourSelected(object sender, RoutedEventArgs e) 
    { 
     var minuteButton = GetTemplateChild("PART_Minute") as ToggleButton;    
     minuteButton.IsChecked = false; 
    } 

    private void MinuteSelected(object sender, RoutedEventArgs e) 
    { 
     var hourButton = GetTemplateChild("PART_Hour") as ToggleButton; 
     hourButton.IsChecked = false; 
    } 

    private void IncreaseClick(object sender, RoutedEventArgs e) 
    { 
     var hourButton = GetTemplateChild("PART_Hour") as ToggleButton; 
     var minuteButton = GetTemplateChild("PART_Minute") as ToggleButton; 

     if (hourButton.IsChecked == true) 
     { 
      if (Hour == 12) 
      { 
       Hour = 1; 
      } 
      else 
      { 
       Hour += 1; 
      } 
     } 
     else if (minuteButton.IsChecked == true) 
     { 
      if (Minute == 59) 
      { 
       Minute = 00; 
      } 
      else 
      { 
       Minute += 1; 
      } 
     } 
    } 

    private void DecreaseClick(object sender, RoutedEventArgs e) 
    { 
     var hourButton = GetTemplateChild("PART_Hour") as ToggleButton; 
     var minuteButton = GetTemplateChild("PART_Minute") as ToggleButton; 

     if (hourButton.IsChecked == true) 
     { 
      if (Hour == 1) 
      { 
       Hour = 12; 
      } 
      else 
      { 
       Hour -= 1; 
      } 
     } 
     else if (minuteButton.IsChecked == true) 
     { 
      if (Minute == 00) 
      { 
       Minute = 59; 
      } 
      else 
      { 
       Minute -= 1; 
      } 
     } 
    } 

    private static void OnHourChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) 
    { 

    } 

    private static void OnMinuteChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) 
    { 

    } 

    static TimePicker() 
    { 
     DefaultStyleKeyProperty.OverrideMetadata(typeof(TimePicker), new FrameworkPropertyMetadata(typeof(TimePicker))); 
    } 
} 

public partial class TimePickerEvents : ResourceDictionary 
{ 
    TimePicker time = new TimePicker(); 

    void PART_IncreaseTime_Click(object sender, RoutedEventArgs e) 
    { 
     time.Hour += 1; 

    } 

} 

XAML

<ToggleButton x:Name="PART_Minute" 
             VerticalAlignment="{TemplateBinding VerticalAlignment}" 
             Margin="0" 
             MinWidth="25" 
             BorderBrush="Transparent" 
             Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=MinuteZeros}"> 
          <ToggleButton.Template> 
           <ControlTemplate TargetType="{x:Type ToggleButton}"> 
             <Grid> 
              <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
                   VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/> 
              <ContentPresenter x:Name="ContentPart" 
                   HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
                   VerticalAlignment="{TemplateBinding VerticalContentAlignment}" 
                   TextBlock.Foreground="#FF605c" Visibility="Collapsed"> 
               <ContentPresenter.Effect> 
                <BlurEffect /> 
               </ContentPresenter.Effect> 
              </ContentPresenter> 
             </Grid> 
            <ControlTemplate.Triggers> 
             <Trigger Property="IsMouseOver" Value="True"> 
              <Setter TargetName="ContentPart" Property="Visibility" Value="Visible" /> 
             </Trigger> 
             <Trigger Property="IsChecked" Value="True"> 
              <Setter Property="FontWeight" Value="Bold" /> 
              <Setter TargetName="ContentPart" Property="Visibility" Value="Visible" /> 
             </Trigger> 
            </ControlTemplate.Triggers> 
           </ControlTemplate> 
          </ToggleButton.Template> 
          <ToggleButton.Style> 
           <Style TargetType="{x:Type ToggleButton}"> 
            <Setter Property="Background" Value="Transparent" /> 
           </Style> 
          </ToggleButton.Style> 
         </ToggleButton> 
+0

這有幫助嗎? [WPF Force Rebind](http://stackoverflow.com/questions/957522/wpf-force-rebind) – Guvante 2012-03-16 21:43:22

回答

0

只想發佈完成此項工作的最終更改。

public static DependencyProperty SelectedTimeProperty = DependencyProperty.Register("SelectedTime", typeof(TimeSpan), typeof(TimePicker), 
     new FrameworkPropertyMetadata((TimeSpan.Zero), new PropertyChangedCallback(OnSelectedTimeChanged))); 

    public TimeSpan SelectedTime 
    { 
     get { return (TimeSpan)GetValue(SelectedTimeProperty); } 
     set { SetValue(SelectedTimeProperty, value); } 
    } 

    private static void OnHourChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) 
    { 
     TimePicker tp = (TimePicker)sender; 

     //TimePicker tp = new TimePicker(); 
     var amButton = tp.GetTemplateChild("PART_AmIndicator") as RadioButton; 
     var pmButton = tp.GetTemplateChild("PART_PmIndicator") as RadioButton; 

     if (pmButton.IsChecked != false) 
     { 
      tp.SelectedTime = new TimeSpan((int.Parse(tp.Hour) + 12), int.Parse(tp.Minute), 0); 
     } 
     else if (amButton.IsChecked != false && (tp.Hour == "12")) 
     { 
      tp.SelectedTime = new TimeSpan(0, int.Parse(tp.Minute), 0); 
     } 
     else 
     { 
      tp.SelectedTime = new TimeSpan(int.Parse(tp.Hour), int.Parse(tp.Minute), 0); 
     } 
    } 

    private static void OnMinuteChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) 
    { 
     //TimePicker tp = new TimePicker(); 
     TimePicker tp = (TimePicker)sender; 

     var amButton = tp.GetTemplateChild("PART_AmIndicator") as RadioButton; 
     var pmButton = tp.GetTemplateChild("PART_PmIndicator") as RadioButton; 

     if (pmButton.IsChecked != false) 
     { 
      tp.SelectedTime = new TimeSpan((int.Parse(tp.Hour) + 12), int.Parse(tp.Minute), 0); 
     } 
     else if (amButton.IsChecked != false && (tp.Hour == "12")) 
     { 
      tp.SelectedTime = new TimeSpan(0, int.Parse(tp.Minute), 0); 
     } 
     else 
     { 
      tp.SelectedTime = new TimeSpan(int.Parse(tp.Hour), int.Parse(tp.Minute), 0); 
     } 
    } 
1

選項1:使用的StringFormat - 不工作,請參閱SO article

選項2:使用StringFormatConverter - 哪個可以工作

擺脫MinuteZeros和使用

<Converters:StringFormatConverter x:Key="StringFormatConverter" /> 

{Binding 
    RelativeSource={RelativeSource TemplatedParent}, 
    Path=Minutes, 
    StringFormatConverter={StaticResource StringFormatConverter}, 
    ConverterParameter=D2 
} 

public class StringFormatConverter : IValueConverter 
{ 
    #region Implementation of IValueConverter 

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     if (value == null) 
     { 
      throw new ArgumentNullException("value"); 
     } 

     var fmt = string.Format("{{0:{0}}}", parameter); 
     return string.Format(fmt, value); 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 

    #endregion 
} 

方案3:我還沒有實現

認沽邏輯在OnHourChanged和OnMinuteChanged處理程序來分鐘和MinutesZeros同步。

+0

如果我這樣做('Path = MinuteZeros'),它會顯示兩位數字,但增加/減少按鈕什麼也不做。如果我將其切換到('Path = Minutes'),增加/減少將起作用,但它不會同時顯示兩個零。 – 2012-03-17 00:24:13