使用依赖项属性的Numeric UpDown控件

本文关键字:Numeric UpDown 控件 属性 依赖 | 更新日期: 2023-09-27 18:27:42

所以我无法理解这一点。我有一个自定义控件,它使用向上/向下按钮来增加/减少切换按钮上显示的时间。Toggles的Content属性显示了HourMinute属性的正确值,现在我正在尝试设置后面的代码以增加值。根据VS2010调试器的说法,正在增加Hour属性的值,但它并没有改变Toggles的内容来反映这一点。我将绑定模式设置为TwoWay,并且我正在使用{binding RelativeSource={RelativeSource TemplatedParent}, Path=Hour, Mode=TwoWay}来绑定到值,因为它位于自定义控件的generic.xaml文件中。关于如何正确更新显示的值,有什么想法吗?

XAML:(删除样式模板以节省空间)

    <Style TargetType="{x:Type local:TimePicker}">
    <Setter Property="Height" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Height}" />
    <Setter Property="Width" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Width}" />
    <Setter Property="HorizontalAlignment" Value="Center" />
    <Setter Property="VerticalAlignment" Value="Center" />
    <Setter Property="FontSize" Value="14" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate>
                <Border Background="{TemplateBinding Background}"
                        BorderBrush="Transparent"
                        BorderThickness="1">
                    <StackPanel  x:Name="PART_Root"
                                 Orientation="Horizontal"
                                 HorizontalAlignment="Center"
                                 VerticalAlignment="{TemplateBinding VerticalAlignment}">
                        <!--Region Hour Button-->
                        <ToggleButton x:Name="PART_Hour"
                                      VerticalAlignment="{TemplateBinding VerticalAlignment}"
                                      Margin="0"
                                      BorderBrush="Transparent"
                                      BorderThickness="0"
                                      Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Hour, Mode=TwoWay, BindsDirectlyToSource=True}">                                
                        </ToggleButton>
                        <!--EndRegion-->
                        <Label HorizontalContentAlignment="{TemplateBinding HorizontalAlignment}"
                               VerticalContentAlignment="{TemplateBinding VerticalAlignment}"
                               FontSize="14"
                               Content=":"/>
                        <!--Region Minute Button-->
                        <ToggleButton x:Name="PART_Minute"
                                      VerticalAlignment="{TemplateBinding VerticalAlignment}"
                                      Margin="0"
                                      BorderBrush="Transparent"
                                      Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Minute}">                                
                        </ToggleButton>
                        <!--EndRegion-->
                        <StackPanel x:Name="PART_IncDecPanel"
                                    HorizontalAlignment="Center"
                                    VerticalAlignment="Center"
                                    Orientation="Vertical">
                            <Grid Height="{Binding ElementName=PART_Hour, Path=ActualHeight}">
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="*"/>
                                    <RowDefinition Height="*"/>
                                </Grid.RowDefinitions>
                                <Viewbox Stretch="Fill" Grid.Row="0">
                                    <!--Region Increase Button-->
                                    <Button x:Name="PART_IncreaseTime"
                                            HorizontalContentAlignment="{TemplateBinding HorizontalAlignment}"
                                            VerticalContentAlignment="{TemplateBinding VerticalAlignment}"
                                            BorderBrush="Transparent"
                                            BorderThickness="0"
                                            FontFamily="Marlett"
                                            Foreground="DimGray"
                                            Content="5"
                                            Padding="0"
                                            Click="PART_IncreaseTime_Click">                                            
                                    </Button>
                                    <!--EndRegion-->
                                </Viewbox >
                                <Viewbox Stretch="Fill" Grid.Row="1">
                                    <!--Region Decrease Button-->
                                    <Button x:Name="PART_DecreaseTime"
                                            HorizontalContentAlignment="{TemplateBinding HorizontalAlignment}"
                                            VerticalContentAlignment="{TemplateBinding VerticalAlignment}"
                                            BorderBrush="Transparent"
                                            BorderThickness="0"
                                            FontFamily="Marlett"
                                            Foreground="DimGray"
                                            Content="6"
                                            Padding="0">                                            
                                    </Button>
                                    <!--EndRegion-->
                                </Viewbox>
                            </Grid>
                        </StackPanel>
                    </StackPanel>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

代码:

public class TimePicker : Control
{
    #region Dependency Property Declarations
    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(string), typeof(TimePicker),
        new FrameworkPropertyMetadata((string)"00", new PropertyChangedCallback(OnMinuteChanged)));        
    #endregion
    #region Properties
    public int Hour
    {
        get { return (int)GetValue(HourProperty); }
        set { SetValue(HourProperty, value); }
    }
    public string Minute
    {
        get { return (string)GetValue(MinuteProperty); }
        set { SetValue(MinuteProperty, value); }
    }
    #endregion
    #region Events
    private static void OnHourChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {
        TimePicker time = new TimePicker();
        time.Hour = (int)e.NewValue;
        MessageBox.Show("Hour changed");
    }
    private static void OnMinuteChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {
    }
    #endregion
    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;
    }
}   

使用依赖项属性的Numeric UpDown控件

不知道为什么要使用切换按钮来显示小时/分钟,我认为Label/TextBlock更适合这样。

将ToggleButtons的绑定更改为

Content="{TemplateBinding Hour}"

然后在代码中,将OnApplyTemplate覆盖为

public override void OnApplyTemplate()
{
    var upButton = GetTemplateChild("PART_IncreaseTime") as Button;
    upButton.Click += IncreaseClick;
    var downButton = GetTemplateChild("PART_DecreaseTime") as Button;
    downButton.Click += DecreaseClick;
}
private void IncreaseClick(object sender, RoutedEventArgs e)
{
    // Here would be a place to see what toggle button is checked 
    // (or which TextBlock last had focus) and increase Hour/Minute
    // based on that info
    Hour += 1;
}
private void DecreaseClick(object sender, RoutedEventArgs e)
{
    // Here would be a place to see what toggle button is checked 
    // (or which TextBlock last had focus) and decreaseHour/Minute
    // based on that info
    Hour -= 1;
}

这应该会让你开始。仅供参考:在您的OnHourChanged和OnMinuteChanged中,发件人是您的控制(TimePicker)。因此,您可以将发件人强制转换为TimePicker并访问您的所有属性。甚至是你的私人财产。

为什么不使用WPF工具包的数字上下控制?http://wpftoolkit.codeplex.com/wikipage?title=NumericUpDown

您所要做的就是以两种方式将其绑定到您的属性。