[#37] Controls: Implement IntegerUpDown
All checks were successful
Test / Run tests (push) Successful in 2m28s
All checks were successful
Test / Run tests (push) Successful in 2m28s
This commit is contained in:
106
Elwig/Controls/IntegerUpDown.cs
Normal file
106
Elwig/Controls/IntegerUpDown.cs
Normal file
@ -0,0 +1,106 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Elwig.Controls {
|
||||
public class IntegerUpDown : TextBox {
|
||||
|
||||
public static readonly DependencyProperty MinimumProperty = DependencyProperty.Register("Miminum", typeof(int?), typeof(IntegerUpDown), new FrameworkPropertyMetadata(null));
|
||||
public int? Minimum {
|
||||
get => (int?)GetValue(MinimumProperty);
|
||||
set => SetValue(MinimumProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty MaximumProperty = DependencyProperty.Register("Maximum", typeof(int?), typeof(IntegerUpDown), new FrameworkPropertyMetadata(null));
|
||||
public int? Maximum {
|
||||
get => (int?)GetValue(MaximumProperty);
|
||||
set => SetValue(MaximumProperty, value);
|
||||
}
|
||||
|
||||
public int? Value {
|
||||
get => int.TryParse(Text, out var res) ? res : null;
|
||||
set => Text = $"{value}";
|
||||
}
|
||||
|
||||
static IntegerUpDown() {
|
||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(IntegerUpDown), new FrameworkPropertyMetadata(typeof(IntegerUpDown)));
|
||||
}
|
||||
|
||||
public IntegerUpDown() {
|
||||
TextChanged += IntegerUpDown_TextChanged;
|
||||
LostFocus += IntegerUpDown_LostFocus;
|
||||
KeyUp += IntegerUpDown_KeyUp;
|
||||
}
|
||||
|
||||
public override void OnApplyTemplate() {
|
||||
var incButton = GetTemplateChild("IncrementButton") as RepeatButton;
|
||||
var decButton = GetTemplateChild("DecrementButton") as RepeatButton;
|
||||
incButton!.Click += IncrementButton_Click;
|
||||
decButton!.Click += DecrementButton_Click;
|
||||
base.OnApplyTemplate();
|
||||
}
|
||||
|
||||
private void IntegerUpDown_TextChanged(object sender, TextChangedEventArgs evt) {
|
||||
var idx = CaretIndex;
|
||||
Text = new string(Text.Where(char.IsAsciiDigit).Take(4).ToArray());
|
||||
CaretIndex = idx;
|
||||
evt.Handled = !(Value >= Minimum && Value <= Maximum);
|
||||
if (idx >= 4) {
|
||||
if (Value < Minimum) {
|
||||
Value = Minimum;
|
||||
} else if (Value > Maximum) {
|
||||
Value = Maximum;
|
||||
}
|
||||
CaretIndex = 4;
|
||||
}
|
||||
}
|
||||
|
||||
private void IntegerUpDown_LostFocus(object sender, RoutedEventArgs evt) {
|
||||
if (Value < Minimum) {
|
||||
Value = Minimum;
|
||||
} else if (Value > Maximum) {
|
||||
Value = Maximum;
|
||||
}
|
||||
}
|
||||
|
||||
private void IncrementButton_Click(object sender, RoutedEventArgs evt) {
|
||||
Value = Math.Min((Value ?? 0) + 1, Maximum ?? int.MaxValue);
|
||||
}
|
||||
|
||||
private void DecrementButton_Click(object sender, RoutedEventArgs evt) {
|
||||
Value = Math.Max((Value ?? 0) - 1, Minimum ?? int.MinValue);
|
||||
}
|
||||
|
||||
private void IntegerUpDown_KeyUp(object sender, KeyEventArgs evt) {
|
||||
switch (evt.Key) {
|
||||
case Key.Up:
|
||||
case Key.Add:
|
||||
case Key.OemPlus:
|
||||
Value = Math.Min((Value ?? 0) + 1, Maximum ?? int.MaxValue);
|
||||
evt.Handled = true;
|
||||
CaretIndex = 4;
|
||||
break;
|
||||
case Key.Down:
|
||||
case Key.Subtract:
|
||||
case Key.OemMinus:
|
||||
Value = Math.Max((Value ?? 0) - 1, Minimum ?? int.MinValue);
|
||||
evt.Handled = true;
|
||||
CaretIndex = 4;
|
||||
break;
|
||||
case Key.PageUp:
|
||||
Value = Math.Min((Value ?? 0) + 10, Maximum ?? int.MaxValue);
|
||||
evt.Handled = true;
|
||||
CaretIndex = 4;
|
||||
break;
|
||||
case Key.PageDown:
|
||||
Value = Math.Max((Value ?? 0) - 10, Minimum ?? int.MinValue);
|
||||
evt.Handled = true;
|
||||
CaretIndex = 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
52
Elwig/Controls/IntegerUpDown.xaml
Normal file
52
Elwig/Controls/IntegerUpDown.xaml
Normal file
@ -0,0 +1,52 @@
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:ctrl="clr-namespace:Elwig.Controls">
|
||||
<Style TargetType="ctrl:IntegerUpDown" BasedOn="{StaticResource {x:Type TextBox}}">
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="ctrl:IntegerUpDown">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="18"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Border x:Name="Border" BorderThickness="1,1,0,1"
|
||||
BorderBrush="{Binding Path=BorderBrush, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"
|
||||
SnapsToDevicePixels="True" Grid.RowSpan="2">
|
||||
<ScrollViewer x:Name="PART_ContentHost" VerticalAlignment="Center"/>
|
||||
</Border>
|
||||
|
||||
<RepeatButton x:Name="IncrementButton" Padding="0" Height="Auto" Width="Auto" BorderThickness="1,1,1,0"
|
||||
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.Row="0" Grid.Column="1">
|
||||
<Path x:Name="IconIncrement" Data="M 0,4 L 4,0 L 8,4 Z" Fill="#FF444444"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||
</RepeatButton>
|
||||
<RepeatButton x:Name="DecrementButton" Padding="0" Height="Auto" Width="Auto" BorderThickness="1,0,1,1"
|
||||
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.Row="1" Grid.Column="1">
|
||||
<Path x:Name="IconDecrement" Data="M 0,0 L 4,4 L 8,0 Z" Fill="#FF444444"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||
</RepeatButton>
|
||||
</Grid>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsEnabled" Value="False">
|
||||
<Setter TargetName="Border" Property="BorderBrush" Value="LightGray"/>
|
||||
<Setter TargetName="IconIncrement" Property="Fill" Value="#FF888888"/>
|
||||
<Setter TargetName="IconDecrement" Property="Fill" Value="#FF888888"/>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Setter Property="TextAlignment" Value="Right"/>
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsEnabled" Value="False">
|
||||
<Setter Property="Foreground" Value="Gray"/>
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</ResourceDictionary>
|
@ -1,5 +1,6 @@
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="/Elwig;component/Controls/UnitTextBox.xaml"/>
|
||||
<ResourceDictionary Source="/Elwig;component/Controls/IntegerUpDown.xaml"/>
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
|
@ -175,9 +175,9 @@
|
||||
</TextBlock>
|
||||
</TextBox.ToolTip>
|
||||
</TextBox>
|
||||
<xctk:IntegerUpDown x:Name="SeasonInput" Grid.ColumnSpan="3" Height="25" Width="56" FontSize="14" Minimum="1000" Maximum="9999"
|
||||
Margin="0,10,100,0" VerticalAlignment="Top" HorizontalAlignment="Right"
|
||||
ValueChanged="SeasonInput_ValueChanged"/>
|
||||
<ctrl:IntegerUpDown x:Name="SeasonInput" Grid.ColumnSpan="3" Height="25" Width="56" FontSize="14" Minimum="1900" Maximum="9999"
|
||||
Margin="0,10,100,0" VerticalAlignment="Top" HorizontalAlignment="Right" Text="2020"
|
||||
TextChanged="SeasonInput_TextChanged"/>
|
||||
<CheckBox x:Name="TodayOnlyInput" Content="Nur heute"
|
||||
HorizontalAlignment="Right" Margin="0,7,18,0" VerticalAlignment="Top" Grid.Column="1" Grid.ColumnSpan="2"
|
||||
Checked="TodayOnlyInput_Changed" Unchecked="TodayOnlyInput_Changed"/>
|
||||
|
@ -1344,8 +1344,8 @@ namespace Elwig.Windows {
|
||||
await RefreshDeliveryListQuery(true);
|
||||
}
|
||||
|
||||
private async void SeasonInput_ValueChanged(object sender, RoutedEventArgs evt) {
|
||||
if (SeasonInput.Value == null) return;
|
||||
private async void SeasonInput_TextChanged(object sender, TextChangedEventArgs evt) {
|
||||
if (SeasonInput.Value == null || TodayOnlyInput == null || AllSeasonsInput == null) return;
|
||||
TodayOnlyInput.IsChecked = false;
|
||||
AllSeasonsInput.IsChecked = false;
|
||||
await RefreshDeliveryListQuery();
|
||||
|
@ -3,7 +3,7 @@
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="clr-namespace:Elwig.Windows"
|
||||
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
|
||||
xmlns:ctrl="clr-namespace:Elwig.Controls"
|
||||
Title="Elwig" Height="390" Width="520" ResizeMode="CanMinimize"
|
||||
Loaded="Window_Loaded" Closing="Window_Closing">
|
||||
<Window.Resources>
|
||||
@ -71,9 +71,9 @@
|
||||
<Grid>
|
||||
<Border BorderBrush="LightGray" BorderThickness="1"/>
|
||||
<Label Content="Saison:" Margin="0,10,100,0" VerticalAlignment="Top" HorizontalAlignment="Center" Padding="2,4,2,4" Height="25"/>
|
||||
<xctk:IntegerUpDown Name="SeasonInput" Height="25" Width="56" FontSize="14" Minimum="1000" Maximum="9999"
|
||||
<ctrl:IntegerUpDown x:Name="SeasonInput" Height="25" Width="56" FontSize="14" Minimum="1900" Maximum="9999"
|
||||
Margin="0,10,0,0" VerticalAlignment="Top" HorizontalAlignment="Center"
|
||||
ValueChanged="SeasonInput_ValueChanged"/>
|
||||
TextChanged="SeasonInput_TextChanged"/>
|
||||
|
||||
<Button x:Name="DeliveryConfirmationButton" Content="Anlieferungsbestätigung"
|
||||
Click="DeliveryConfirmationButton_Click"
|
||||
|
@ -14,6 +14,7 @@ using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Elwig.Windows {
|
||||
@ -147,7 +148,7 @@ namespace Elwig.Windows {
|
||||
}
|
||||
|
||||
protected override Task OnRenewContext(AppDbContext ctx) {
|
||||
SeasonInput_ValueChanged(null, null);
|
||||
SeasonInput_TextChanged(null, null);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
@ -159,7 +160,7 @@ namespace Elwig.Windows {
|
||||
Height = 390;
|
||||
}
|
||||
|
||||
private async void SeasonInput_ValueChanged(object? sender, RoutedEventArgs? evt) {
|
||||
private async void SeasonInput_TextChanged(object? sender, TextChangedEventArgs? evt) {
|
||||
using var ctx = new AppDbContext();
|
||||
var s0 = await ctx.Seasons.FindAsync(SeasonInput.Value);
|
||||
var valid = (s0 != null);
|
||||
|
Reference in New Issue
Block a user