使用依赖项属性的Numeric UpDown控件
本文关键字:Numeric UpDown 控件 属性 依赖 | 更新日期: 2023-09-27 18:27:42
所以我无法理解这一点。我有一个自定义控件,它使用向上/向下按钮来增加/减少切换按钮上显示的时间。Toggles的Content
属性显示了Hour
和Minute
属性的正确值,现在我正在尝试设置后面的代码以增加值。根据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;
}
}
不知道为什么要使用切换按钮来显示小时/分钟,我认为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
您所要做的就是以两种方式将其绑定到您的属性。