Where is the WPF Numeric UpDown control?

后端 未结 13 1738
伪装坚强ぢ
伪装坚强ぢ 2020-11-30 00:02

Getting into the first serious WPF project. It seems like there are a lot of basic controls flat out missing. Specifically, I am looking for the Numeric UpDown control. W

相关标签:
13条回答
  • 2020-11-30 00:42

    I made my own;

    the xaml

    <StackPanel Orientation="Horizontal">
        <TextBox x:Name="txtNum" x:FieldModifier="private" Margin="5,5,0,5" Width="50" Text="0" TextChanged="txtNum_TextChanged" />
        <Button x:Name="cmdUp" x:FieldModifier="private" Margin="5,5,0,5" Content="˄" Width="20" Click="cmdUp_Click" />
        <Button x:Name="cmdDown" x:FieldModifier="private" Margin="0,5,0,5"  Content="˅" Width="20" Click="cmdDown_Click" />
    </StackPanel>
    

    and the code behind

    private int _numValue = 0;
    
    public int NumValue
    {
        get {  return _numValue; }
        set
        {
            _numValue = value;
            txtNum.Text = value.ToString();
        }
    }
    
    public NumberUpDown()
    {
        InitializeComponent();
        txtNum.Text = _numValue.ToString();
    }
    
    private void cmdUp_Click(object sender, RoutedEventArgs e)
    {
        NumValue++;
    }
    
    private void cmdDown_Click(object sender, RoutedEventArgs e)
    {
        NumValue--;
    }
    
    private void txtNum_TextChanged(object sender, TextChangedEventArgs e)
    {
        if (txtNum == null)
        {
            return;
        }
    
        if (!int.TryParse(txtNum.Text, out _numValue))
            txtNum.Text = _numValue.ToString();
    }
    
    0 讨论(0)
  • 2020-11-30 00:42

    Here is another open source control that has many different input methods (mouse drag, mouse wheel, cursor keys, textbox editing), supports many data types and use cases:

    https://github.com/Dirkster99/NumericUpDownLib

    0 讨论(0)
  • 2020-11-30 00:47

    Go to NugetPackage manager of you project-> Browse and search for mahApps.Metro -> install package into you project. You will see Reference added: MahApps.Metro. Then in you XAML code add:

    "xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls"

    Where you want to use your object add:

    <mah:NumericUpDown x:Name="NumericUpDown" ... /> 
    

    Enjoy the full extensibility of the object (Bindings, triggers and so on...).

    0 讨论(0)
  • 2020-11-30 00:48

    Let's enjoy some hacky things:
    Here is a Style of Slider as a NumericUpDown, simple and easy to use, without any hidden code or third party library.

    <Style TargetType="{x:Type Slider}">
        <Style.Resources>
            <Style x:Key="RepeatButtonStyle" TargetType="{x:Type RepeatButton}">
                <Setter Property="Focusable" Value="false" />
                <Setter Property="IsTabStop" Value="false" />
                <Setter Property="Padding" Value="0" />
                <Setter Property="Width" Value="20" />
            </Style>
        </Style.Resources>
        <Setter Property="Stylus.IsPressAndHoldEnabled" Value="false" />
        <Setter Property="SmallChange" Value="1" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Slider}">
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition />
                            <RowDefinition />
                        </Grid.RowDefinitions>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition />
                            <ColumnDefinition Width="Auto" />
                        </Grid.ColumnDefinitions>
                        <TextBox Grid.RowSpan="2"
                                 Height="Auto"
                                 Margin="0" Padding="0" VerticalAlignment="Stretch" VerticalContentAlignment="Center"
                                 Text="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=Value}" />
                        <RepeatButton Grid.Row="0" Grid.Column="1" Command="{x:Static Slider.IncreaseLarge}" Style="{StaticResource RepeatButtonStyle}">
                            <Path Data="M4,0 L0,4 8,4 Z" Fill="Black" />
                        </RepeatButton>
                        <RepeatButton Grid.Row="1" Grid.Column="1" Command="{x:Static Slider.DecreaseLarge}" Style="{StaticResource RepeatButtonStyle}">
                            <Path Data="M0,0 L4,4 8,0 Z" Fill="Black" />
                        </RepeatButton>
                        <Border x:Name="TrackBackground" Visibility="Collapsed">
                            <Rectangle x:Name="PART_SelectionRange" Visibility="Collapsed" />
                        </Border>
                        <Thumb x:Name="Thumb" Visibility="Collapsed" />
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    
    0 讨论(0)
  • 2020-11-30 00:54

    This is example of my own UserControl with Up and Down key catching.

    Xaml code:

    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="13" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="13" />
            <RowDefinition Height="13" />
        </Grid.RowDefinitions>
        <TextBox Name="NUDTextBox"  Grid.Column="0" Grid.Row="0" Grid.RowSpan="2" TextAlignment="Right" PreviewKeyDown="NUDTextBox_PreviewKeyDown" PreviewKeyUp="NUDTextBox_PreviewKeyUp" TextChanged="NUDTextBox_TextChanged"/>
        <RepeatButton Name="NUDButtonUP"  Grid.Column="1" Grid.Row="0" FontSize="8" FontFamily="Marlett" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Click="NUDButtonUP_Click">5</RepeatButton>
        <RepeatButton Name="NUDButtonDown"  Grid.Column="1" Grid.Row="1" FontSize="8"  FontFamily="Marlett" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Height="13" VerticalAlignment="Bottom" Click="NUDButtonDown_Click">6</RepeatButton>
    </Grid>
    

    And the code:

    public partial class NumericUpDown : UserControl
    {
        int minvalue = 0, 
            maxvalue = 100,
            startvalue = 10;
        public NumericUpDown()
        {
            InitializeComponent();
            NUDTextBox.Text = startvalue.ToString();
        }
    
        private void NUDButtonUP_Click(object sender, RoutedEventArgs e)
        {
            int number;
            if (NUDTextBox.Text != "") number = Convert.ToInt32(NUDTextBox.Text);
            else number = 0;
            if (number < maxvalue)
                NUDTextBox.Text = Convert.ToString(number + 1); 
        }
    
        private void NUDButtonDown_Click(object sender, RoutedEventArgs e)
        {
            int number;
            if (NUDTextBox.Text != "") number = Convert.ToInt32(NUDTextBox.Text);
            else number = 0;
            if (number > minvalue)
                NUDTextBox.Text = Convert.ToString(number - 1); 
        }
    
        private void NUDTextBox_PreviewKeyDown(object sender, KeyEventArgs e)
        {
    
            if (e.Key == Key.Up)
            {
                NUDButtonUP.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));
                typeof(Button).GetMethod("set_IsPressed", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(NUDButtonUP, new object[] { true }); 
            }
    
    
            if (e.Key == Key.Down)
            {
                NUDButtonDown.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));
                typeof(Button).GetMethod("set_IsPressed", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(NUDButtonDown, new object[] { true }); 
            }
        }
    
        private void NUDTextBox_PreviewKeyUp(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Up)
                typeof(Button).GetMethod("set_IsPressed", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(NUDButtonUP, new object[] { false });
    
            if (e.Key == Key.Down)
                typeof(Button).GetMethod("set_IsPressed", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(NUDButtonDown, new object[] { false });
        }
    
        private void NUDTextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            int number = 0;
            if (NUDTextBox.Text!="")
                if (!int.TryParse(NUDTextBox.Text, out number)) NUDTextBox.Text = startvalue.ToString();
            if (number > maxvalue)  NUDTextBox.Text = maxvalue.ToString();
            if (number < minvalue) NUDTextBox.Text = minvalue.ToString();
            NUDTextBox.SelectionStart = NUDTextBox.Text.Length;
    
        }
    
    }
    
    0 讨论(0)
  • 2020-11-30 00:57
    <ResourceDictionary
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:numericButton2">
    
    
        <Style TargetType="{x:Type local:NumericUpDown}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type local:NumericUpDown}">              
                            <Grid>
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="*"/>
                                    <RowDefinition Height="*"/>
                                    <RowDefinition Height="*"/>
                                </Grid.RowDefinitions>
                                <RepeatButton Grid.Row="0" Name="Part_UpButton"/>
                                <ContentPresenter Grid.Row="1"></ContentPresenter>
                                <RepeatButton Grid.Row="2" Name="Part_DownButton"/>
                            </Grid>                  
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ResourceDictionary>
    
        <Window x:Class="numericButton2.MainWindow"
                xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                xmlns:local="clr-namespace:numericButton2"
                Title="MainWindow" Height="350" Width="525">
            <Grid>
                <local:NumericUpDown Margin="181,94,253,161" x:Name="ufuk" StepValue="4" Minimum="0" Maximum="20">            
                </local:NumericUpDown>
                <TextBlock Margin="211,112,279,0" Text="{Binding ElementName=ufuk, Path=Value}" Height="20" VerticalAlignment="Top"></TextBlock>
            </Grid>
        </Window>
    public class NumericUpDown : Control
    {
        private RepeatButton _UpButton;
        private RepeatButton _DownButton;
        public readonly static DependencyProperty MaximumProperty;
        public readonly static DependencyProperty MinimumProperty;
        public readonly static DependencyProperty ValueProperty;
        public readonly static DependencyProperty StepProperty;   
        static NumericUpDown()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(NumericUpDown), new FrameworkPropertyMetadata(typeof(NumericUpDown)));
            MaximumProperty = DependencyProperty.Register("Maximum", typeof(int), typeof(NumericUpDown), new UIPropertyMetadata(10));
            MinimumProperty = DependencyProperty.Register("Minimum", typeof(int), typeof(NumericUpDown), new UIPropertyMetadata(0));
            StepProperty = DependencyProperty.Register("StepValue", typeof(int), typeof(NumericUpDown), new FrameworkPropertyMetadata(5));
            ValueProperty = DependencyProperty.Register("Value", typeof(int), typeof(NumericUpDown), new FrameworkPropertyMetadata(0));
        }
        #region DpAccessior
        public int Maximum
        {
            get { return (int)GetValue(MaximumProperty); }
            set { SetValue(MaximumProperty, value); }
        }
        public int Minimum
        {
            get { return (int)GetValue(MinimumProperty); }
            set { SetValue(MinimumProperty, value); }
        }
        public int Value
        {
            get { return (int)GetValue(ValueProperty); }
            set { SetCurrentValue(ValueProperty, value); }
        }
        public int StepValue
        {
            get { return (int)GetValue(StepProperty); }
            set { SetValue(StepProperty, value); }
        }
        #endregion
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            _UpButton = Template.FindName("Part_UpButton", this) as RepeatButton;
            _DownButton = Template.FindName("Part_DownButton", this) as RepeatButton;
            _UpButton.Click += _UpButton_Click;
            _DownButton.Click += _DownButton_Click;
        }
    
        void _DownButton_Click(object sender, RoutedEventArgs e)
        {
            if (Value > Minimum)
            {
                Value -= StepValue;
                if (Value < Minimum)
                    Value = Minimum;
            }
        }
    
        void _UpButton_Click(object sender, RoutedEventArgs e)
        {
            if (Value < Maximum)
            {
                Value += StepValue;
                if (Value > Maximum)
                    Value = Maximum;
            }
        }
    
    }
    
    0 讨论(0)
提交回复
热议问题