Сделайте стандартное обновление свойства вместе с DependencyProperty - PullRequest
0 голосов
/ 17 марта 2012

Я, возможно, совершенно не согласен с этим, но клянусь, я помню, что где-то читал, как это сделать, я просто не могу этого найти.У меня есть DependencyProperty Minutes как часть пользовательского элемента управления TimePicker.Это тип данных int, так как это был единственный способ заставить работать кнопку увеличения / уменьшения.Проблема в том, что минуты от 1 до 9 отображаются без начального нуля.Чтобы обойти это, я добавил стандартное свойство MinuteZeros, которое преобразует значение Minutes в string и использует ToString("00").Это свойство привязано к отображаемому контенту.Теперь, когда я нажимаю кнопки увеличения / уменьшения, он не обновляется.Как связать Minutes и MinuteZeros, чтобы они автоматически обновляли друг друга?

Код:

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>

Ответы [ 2 ]

1 голос
/ 17 марта 2012

Вариант 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 для синхронизации минут и минут.

0 голосов
/ 24 марта 2012

Просто хотел опубликовать последние изменения, которые сделали эту работу.

    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);
        }
    }
...