Reimplement TimeSpanEditor, fixes #8

This commit is contained in:
jogibear9988 2016-04-09 11:58:57 +02:00
Родитель ccf1918046
Коммит b4bf83e49f
3 изменённых файлов: 217 добавлений и 17 удалений

Просмотреть файл

@ -26,6 +26,16 @@ namespace SimpleSample
public static readonly DependencyProperty TestTimeSpanProperty =
DependencyProperty.Register("TestTimeSpan", typeof(TimeSpan), typeof(TestControl), new PropertyMetadata(new TimeSpan(4, 3, 55, 34, 345)));
public TimeSpan TestTimeSpan2
{
get { return (TimeSpan)GetValue(TestTimeSpan2Property); }
set { SetValue(TestTimeSpan2Property, value); }
}
// Using a DependencyProperty as the backing store for TestTimeSpan2. This enables animation, styling, binding, etc...
public static readonly DependencyProperty TestTimeSpan2Property =
DependencyProperty.Register("TestTimeSpan2", typeof(TimeSpan), typeof(TestControl), new PropertyMetadata(TimeSpan.FromMinutes(-55)));
}
}

Просмотреть файл

@ -2,18 +2,75 @@
xmlns="http://schemas.microsoft.com/netfx/2007/xaml/presentation"
xmlns:widgets="clr-namespace:ICSharpCode.WpfDesign.Designer.Controls"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<StackPanel Orientation="Horizontal" >
<widgets:NumericUpDown Value="{Binding Days}" />
<TextBlock Text="d" />
<widgets:NumericUpDown Value="{Binding Hours}" />
<TextBlock Text="h" />
<widgets:NumericUpDown Value="{Binding Minutes}" />
<TextBlock Text="m" />
<widgets:NumericUpDown Value="{Binding Seconds}" />
<TextBlock Text="s" />
<widgets:NumericUpDown Value="{Binding MiliSeconds}" />
x:Name="root"
>
<UserControl.Resources>
<Style x:Key="FocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="2" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<SolidColorBrush x:Key="OptionMark.Static.Background" Color="#FFFFFFFF"/>
<SolidColorBrush x:Key="OptionMark.Static.Border" Color="#FF707070"/>
<Style x:Key="OptionMarkFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="14,0,0,0" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="negativeCheckbox" TargetType="{x:Type CheckBox}">
<Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
<Setter Property="Background" Value="{StaticResource OptionMark.Static.Background}"/>
<Setter Property="BorderBrush" Value="{StaticResource OptionMark.Static.Border}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<Grid x:Name="templateRoot" Background="Transparent" SnapsToDevicePixels="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid x:Name="markGrid">
<TextBlock Margin="0,-2,0,0" x:Name="optionMark" FontWeight="Bold" Text="-"></TextBlock>
</Grid>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="HasContent" Value="true">
<Setter Property="FocusVisualStyle" Value="{StaticResource OptionMarkFocusVisual}"/>
<Setter Property="Padding" Value="4,-1,0,0"/>
</Trigger>
<Trigger Property="IsChecked" Value="true">
<Setter Property="Opacity" TargetName="optionMark" Value="1"/>
</Trigger>
<Trigger Property="IsChecked" Value="False">
<Setter Property="Opacity" TargetName="optionMark" Value="0"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<StackPanel Orientation="Horizontal" DataContext="{Binding ElementName=root}">
<CheckBox Margin="2,0,2,0" VerticalAlignment="Center" Style="{StaticResource negativeCheckbox}" IsThreeState="False" IsChecked="{Binding Neagtive}"></CheckBox>
<widgets:NumericUpDown MinWidth="40" Value="{Binding Days}" Minimum="-1" Maximum="10675199" />
<TextBlock Text="d " />
<widgets:NumericUpDown MinWidth="36" Value="{Binding Hours}" Minimum="-1" Maximum="25" />
<TextBlock Text="h " />
<widgets:NumericUpDown MinWidth="36" Value="{Binding Minutes}" Minimum="-1" Maximum="60" />
<TextBlock Text="m " />
<widgets:NumericUpDown MinWidth="36" Value="{Binding Seconds}" Minimum="-1" Maximum="60" />
<TextBlock Text="s " />
<widgets:NumericUpDown MinWidth="44" Value="{Binding MiliSeconds}" Minimum="-1" Maximum="1000" />
<TextBlock Text="ms" />
</StackPanel>
</UserControl>

Просмотреть файл

@ -15,6 +15,7 @@ namespace ICSharpCode.WpfDesign.Designer.PropertyGrid.Editors
public TimeSpanEditor()
{
SpecialInitializeComponent();
DataContextChanged += new DependencyPropertyChangedEventHandler(NumberEditor_DataContextChanged);
}
/// <summary>
@ -32,6 +33,67 @@ namespace ICSharpCode.WpfDesign.Designer.PropertyGrid.Editors
this.InitializeComponent();
}
public PropertyNode PropertyNode
{
get { return DataContext as PropertyNode; }
}
void NumberEditor_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
if (PropertyNode == null)
return;
var value = (TimeSpan) PropertyNode.Value;
if (value < TimeSpan.Zero)
{
this.Neagtive = true;
value = value.Negate();
}
this.Days = value.Days;
this.Hours = value.Hours;
this.Minutes = value.Minutes;
this.Seconds = value.Seconds;
this.MiliSeconds = value.Milliseconds;
}
private void UpdateValue()
{
var ts = new TimeSpan(this.Days, this.Hours, this.Minutes, this.Seconds, this.MiliSeconds);
if (this.Neagtive)
ts = ts.Negate();
PropertyNode.Value = ts;
}
public bool Neagtive
{
get { return (bool)GetValue(NeagtiveProperty); }
set { SetValue(NeagtiveProperty, value); }
}
// Using a DependencyProperty as the backing store for Neagtive. This enables animation, styling, binding, etc...
public static readonly DependencyProperty NeagtiveProperty =
DependencyProperty.Register("Neagtive", typeof(bool), typeof(TimeSpanEditor), new PropertyMetadata(false));
private static void OnNeagtivePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var ctl = (TimeSpanEditor)d;
if (ctl.Hours > 23)
{
ctl.Days++;
ctl.Hours = 0;
}
else if (ctl.Hours < 0)
{
ctl.Days--;
ctl.Hours = 23;
}
ctl.UpdateValue();
}
public int Days
{
get { return (int)GetValue(DaysProperty); }
@ -40,7 +102,14 @@ namespace ICSharpCode.WpfDesign.Designer.PropertyGrid.Editors
// Using a DependencyProperty as the backing store for Days. This enables animation, styling, binding, etc...
public static readonly DependencyProperty DaysProperty =
DependencyProperty.Register("Days", typeof(int), typeof(TimeSpanEditor), new PropertyMetadata());
DependencyProperty.Register("Days", typeof(int), typeof(TimeSpanEditor), new PropertyMetadata(OnDaysPropertyChanged));
private static void OnDaysPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var ctl = (TimeSpanEditor)d;
ctl.UpdateValue();
}
public int Hours
{
@ -50,7 +119,24 @@ namespace ICSharpCode.WpfDesign.Designer.PropertyGrid.Editors
// Using a DependencyProperty as the backing store for Hours. This enables animation, styling, binding, etc...
public static readonly DependencyProperty HoursProperty =
DependencyProperty.Register("Hours", typeof(int), typeof(TimeSpanEditor), new PropertyMetadata());
DependencyProperty.Register("Hours", typeof(int), typeof(TimeSpanEditor), new PropertyMetadata(OnHoursPropertyChanged));
private static void OnHoursPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var ctl = (TimeSpanEditor) d;
if (ctl.Hours > 23)
{
ctl.Days++;
ctl.Hours = 0;
}
else if (ctl.Hours < 0)
{
ctl.Days--;
ctl.Hours = 23;
}
ctl.UpdateValue();
}
public int Minutes
{
@ -60,8 +146,24 @@ namespace ICSharpCode.WpfDesign.Designer.PropertyGrid.Editors
// Using a DependencyProperty as the backing store for Minutes. This enables animation, styling, binding, etc...
public static readonly DependencyProperty MinutesProperty =
DependencyProperty.Register("Minutes", typeof(int), typeof(TimeSpanEditor), new PropertyMetadata());
DependencyProperty.Register("Minutes", typeof(int), typeof(TimeSpanEditor), new PropertyMetadata(OnMinutesPropertyChanged));
private static void OnMinutesPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var ctl = (TimeSpanEditor)d;
if (ctl.Minutes > 59)
{
ctl.Hours++;
ctl.Minutes = 0;
}
else if (ctl.Minutes < 0)
{
ctl.Hours--;
ctl.Minutes = 59;
}
ctl.UpdateValue();
}
public int Seconds
{
@ -71,8 +173,24 @@ namespace ICSharpCode.WpfDesign.Designer.PropertyGrid.Editors
// Using a DependencyProperty as the backing store for Seconds. This enables animation, styling, binding, etc...
public static readonly DependencyProperty SecondsProperty =
DependencyProperty.Register("Seconds", typeof(int), typeof(TimeSpanEditor), new PropertyMetadata());
DependencyProperty.Register("Seconds", typeof(int), typeof(TimeSpanEditor), new PropertyMetadata(OnSecondsPropertyChanged));
private static void OnSecondsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var ctl = (TimeSpanEditor)d;
if (ctl.Seconds > 59)
{
ctl.Minutes++;
ctl.Seconds = 0;
}
else if (ctl.Seconds < 0)
{
ctl.Minutes--;
ctl.Seconds = 59;
}
ctl.UpdateValue();
}
public int MiliSeconds
{
get { return (int)GetValue(MiliSecondsProperty); }
@ -81,8 +199,23 @@ namespace ICSharpCode.WpfDesign.Designer.PropertyGrid.Editors
// Using a DependencyProperty as the backing store for MiliSeconds. This enables animation, styling, binding, etc...
public static readonly DependencyProperty MiliSecondsProperty =
DependencyProperty.Register("MiliSeconds", typeof(int), typeof(TimeSpanEditor), new PropertyMetadata());
DependencyProperty.Register("MiliSeconds", typeof(int), typeof(TimeSpanEditor), new PropertyMetadata(OnMiliSecondsPropertyChanged));
private static void OnMiliSecondsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var ctl = (TimeSpanEditor)d;
if (ctl.MiliSeconds > 999)
{
ctl.Seconds++;
ctl.MiliSeconds = 0;
}
else if (ctl.MiliSeconds < 0)
{
ctl.Seconds--;
ctl.MiliSeconds = 999;
}
ctl.UpdateValue();
}
}
}