使用依赖项属性的Numericupdown控件

时间:2012-03-14 14:21:16

标签: c# wpf binding callback dependency-properties

所以我无法理解这一点。我有一个自定义控件,使用向上/向下按钮来增加/减少切换按钮上显示的时间。我有Toggles的Content属性显示HourMinute属性的正确值,我现在正尝试设置代码隐藏以增加值。根据VS2010调试器,它 增加了Hour属性的值,但它没有改变Toggles的内容来反映这一点。我将绑定模式设置为TwoWay,并且我使用{绑定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;

    }
}   

2 个答案:

答案 0 :(得分:1)

不确定为什么使用Togglebutton来显示小时/分钟,我认为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并访问所有属性。甚至是你的私人财产。

答案 1 :(得分:0)

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

您所要做的就是双向将它绑定到您的属性。