¿Dónde está el control WPF Numeric UpDown?

124

Entrar en el primer proyecto serio de WPF. Parece que faltan muchos controles básicos. Específicamente, estoy buscando el control numérico UpDown. ¿Hubo un lanzamiento fuera de banda que me perdí? Realmente no tengo ganas de escribir mi propio control.

No quiero usar WindowsFormHost y colocar un WinForm ctl en él. Quiero que sea completamente WPF sin ningún tipo de basura heredada.

Gracias

AngryHacker
fuente
44
El kit de herramientas extendido de WPF tiene uno: ¡ NumericUpDown ! texto alternativo
Eduardo Molteni
20
Este único comentario es el mayor impulsor de tráfico a mi blog de todos los tiempos. Hasta el día de hoy. Divertidísimo.
Kevin Moore
1
posible duplicado de Good NumericUpDown equivalente en WPF?
J c
3
La pregunta es "¿dónde está el control UpDown numérico de WPF?". Ninguna de estas respuestas responde a esa pregunta. Esperaría que el tipo de respuesta sea de la forma "decidieron deshacerse de ella en wpf porque ...". Sin embargo, no sé esta respuesta
Asimilater
2
El Kit de herramientas de WPF crea muchos más problemas de los que resuelve, contiene bastantes errores obvios; y no hay control NumericUpDown de Microsoft ... demonios, ¿WPF está vivo?
j00hi

Respuestas:

48

Simplemente use el IntegerUpDowncontrol en el kit de herramientas xtended wpf . Puede usarlo así:

  1. Agregue a su XAML el siguiente espacio de nombres:

    xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"

  2. En su XAML donde desea usar el control:

    <xctk:IntegerUpDown Name="myUpDownControl" />

Apilado
fuente
66
Para aquellos que se preguntan / no se sienten cómodos con los controles de código cerrado de terceros, tenga en cuenta que la versión gratuita de esta biblioteca se publica bajo la Licencia pública de Microsoft, lo que básicamente significa que obtiene el código fuente completo detrás (lea el texto completo de la licencia para más detalles). Los controles UpDown son parte de la versión gratuita. También hay una versión paga de la biblioteca que contiene muchos más controles / temas.
jrh
¿Hay alguna manera de que estos controles WPF personalizados se muestren en VS Toolbox para mayor comodidad? No pude encontrarlos en 'Herramientas -> Elegir elementos de Toolbox'.
aviador
2
Cabe señalar que a partir de la versión v3.7.0, la versión de código abierto de wpftoolkit se proporciona bajo una licencia no comercial patentada en lugar de MS-PL ( referencia )
Jordoff
46

Hice el mío;

el 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>

y el código detrás

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();
}
Miguel
fuente
el evento textChanged no existe para un cuadro de texto en WPF .net 4
AliR
Este método tiene algunas limitaciones, 1) TextBox no se estira horizontalmente con el control como lo hace Winforms, y menos importante, 2) a diferencia de Winforms NumericUpDown, este control permite el estiramiento vertical, lo cual es inofensivo pero parece un poco tonto . Tenga en cuenta que la solución en la respuesta de Sonorx no tiene estos problemas.
jrh
2
NumValue debería ser una propiedad de dependencia para permitir el enlace, también otras propiedades como MinValue y MaxValue serían buenas.
Konrad
Esta solución es poco convincente. Es un control personalizado sin soporte para enlace de datos wpf, eventos enrutados y comandos.
Xam
18

Este es un ejemplo de mi propio UserControl con captura de teclas arriba y abajo.

Código Xaml:

<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>

Y el codigo:

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;

    }

}
Sonorx
fuente
2
¿Se garantiza que la fuente "Marlett" existe en el sistema del usuario?
Qwertie
@Qwertie Es por defecto en Windows desde 3.11, AFAIR.
Spook
Esta es una buena solución y parece funcionar también con UWP XAML. Acabo de tener un pequeño problema con los métodos PreviewKeyDown / PreviewKeyUP.
raddevus
10
<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;
        }
    }

}
vercin
fuente
9

Las respuestas dadas están bien. Sin embargo, quería que los botones se ocultaran automáticamente cuando el mouse dejara el control. Aquí está mi código basado en la respuesta de vercin anterior:

Estilo

<Style TargetType="{x:Type v:IntegerTextBox}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type v:IntegerTextBox}">
                    <Grid Background="Transparent">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="*"/>
                            <RowDefinition Height="*"/>
                        </Grid.RowDefinitions>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*"/>
                            <ColumnDefinition Width="Auto"/>
                        </Grid.ColumnDefinitions>
                        <TextBox Name="tbmain" Grid.ColumnSpan="2" Grid.RowSpan="2"
                                 Text="{Binding Value, Mode=TwoWay, NotifyOnSourceUpdated=True, 
                            NotifyOnValidationError=True, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type v:IntegerTextBox}}}" 
                                               Style="{StaticResource ValidationStyle}" />
                        <RepeatButton Name="PART_UpButton" BorderThickness="0" Grid.Column="1" Grid.Row="0"
                                      Width="13" Background="Transparent">
                            <Path Fill="Black" Data="M 0 3 L 6 3 L 3 0 Z"/>
                        </RepeatButton>
                        <RepeatButton Name="PART_DownButton" BorderThickness="0" Grid.Column="1" Grid.Row="1"
                                      Width="13" Background="Transparent">
                            <Path Fill="Black" Data="M 0 0 L 3 3 L 6 0 Z"/>
                        </RepeatButton>

                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver"  Value="False">
                            <Setter Property="Visibility" TargetName="PART_UpButton" Value="Collapsed"/>
                            <Setter Property="Visibility" TargetName="PART_DownButton" Value="Collapsed"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

Código

public partial class IntegerTextBox : UserControl
{
    public IntegerTextBox()
    {
        InitializeComponent();
    }

    public int Maximum
    {
        get { return (int)GetValue(MaximumProperty); }
        set { SetValue(MaximumProperty, value); }
    }
    public readonly static DependencyProperty MaximumProperty = DependencyProperty.Register(
        "Maximum", typeof(int), typeof(IntegerTextBox), new UIPropertyMetadata(int.MaxValue));



    public int Minimum
    {
        get { return (int)GetValue(MinimumProperty); }
        set { SetValue(MinimumProperty, value); }
    }
    public readonly static DependencyProperty MinimumProperty = DependencyProperty.Register(
        "Minimum", typeof(int), typeof(IntegerTextBox), new UIPropertyMetadata(int.MinValue));


    public int Value
    {
        get { return (int)GetValue(ValueProperty); }
        set { SetCurrentValue(ValueProperty, value); }
    }
    public readonly static DependencyProperty ValueProperty = DependencyProperty.Register(
        "Value", typeof(int), typeof(IntegerTextBox), new UIPropertyMetadata(0, (o,e)=>
        {
            IntegerTextBox tb = (IntegerTextBox)o;
            tb.RaiseValueChangedEvent(e);
        }));

    public event EventHandler<DependencyPropertyChangedEventArgs> ValueChanged;
    private void RaiseValueChangedEvent(DependencyPropertyChangedEventArgs e)
    {
        ValueChanged?.Invoke(this, e);
    }


    public int Step
    {
        get { return (int)GetValue(StepProperty); }
        set { SetValue(StepProperty, value); }
    }
    public readonly static DependencyProperty StepProperty = DependencyProperty.Register(
        "Step", typeof(int), typeof(IntegerTextBox), new UIPropertyMetadata(1));



    RepeatButton _UpButton;
    RepeatButton _DownButton;
    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        _UpButton = Template.FindName("PART_UpButton", this) as RepeatButton;
        _DownButton = Template.FindName("PART_DownButton", this) as RepeatButton;
        _UpButton.Click += btup_Click;
        _DownButton.Click += btdown_Click;
    }


    private void btup_Click(object sender, RoutedEventArgs e)
    {
        if (Value < Maximum)
        {
            Value += Step;
            if (Value > Maximum)
                Value = Maximum;
        }
    }

    private void btdown_Click(object sender, RoutedEventArgs e)
    {
        if (Value > Minimum)
        {
            Value -= Step;
            if (Value < Minimum)
                Value = Minimum;
        }
    }

}
Ron
fuente
La mejor respuesta aquí. Uso adecuado de las propiedades de dependencia.
Konrad
5

Usar VerticalScrollBarcon elTextBlock control en WPF. En su código detrás, agregue el siguiente código:

En el constructor, defina un controlador de eventos para la barra de desplazamiento:

scrollBar1.ValueChanged += new RoutedPropertyChangedEventHandler<double>(scrollBar1_ValueChanged);
scrollBar1.Minimum = 0;
scrollBar1.Maximum = 1;
scrollBar1.SmallChange = 0.1;

Luego, en el controlador de eventos, agregue:

void scrollBar1_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
    FteHolderText.Text = scrollBar1.Value.ToString();
}

Aquí está el fragmento original de mi código ... haga los cambios necesarios ... :)

public NewProjectPlan()
{
    InitializeComponent();

    this.Loaded += new RoutedEventHandler(NewProjectPlan_Loaded);

    scrollBar1.ValueChanged += new RoutedPropertyChangedEventHandler<double>(scrollBar1_ValueChanged);
    scrollBar1.Minimum = 0;
    scrollBar1.Maximum = 1;
    scrollBar1.SmallChange = 0.1;

    // etc...
}

void scrollBar1_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
    FteHolderText.Text = scrollBar1.Value.ToString();
}
Abhinav Wase
fuente
1
su solución es muy inteligente, sin embargo, los botones funcionan en orden inverso (el botón arriba disminuye el valor mientras que el botón abajo lo aumenta). He encontrado otro hilo que puede ser una ayuda para resolver ese problema: stackoverflow.com/a/27246296/637968 - solo gire la barra de desplazamiento
Mike
5

Puede usar el control NumericUpDown para WPF escrito por mí como parte de la biblioteca WPFControls .

Alex Titarenko
fuente
Una pequeña biblioteca agradable y muestra cómo se debe escribir un control numérico arriba / abajo. El único problema que tuve fue tener que volver a hacer referencia al ensamblado de controles en la demostración e instalar MSHTML desde nuget. ¡Gracias!
sargentoKK
Gran trabajo con la biblioteca. Muy útil. Gracias.
namg_engr
5

Discúlpate por seguir respondiendo preguntas de 9 años.

He seguido la respuesta de @ Micheal y funciona.

Lo hago como UserControl donde puedo arrastrar y soltar como elementos de controles. Uso el tema MaterialDesign de Nuget para obtener el icono de Chevron y el efecto de ondulación de los botones.

El NumericUpDown en ejecución de Micheal con modificación será el siguiente:

ingrese la descripción de la imagen aquí

El código para el control del usuario: -

TemplateNumericUpDown.xaml

<UserControl x:Class="UserControlTemplate.TemplateNumericUpDown"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:UserControlTemplate"
             xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
             mc:Ignorable="d" MinHeight="48">
    <Grid Background="{DynamicResource {x:Static SystemColors.WindowFrameBrushKey}}">
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition Width="60"/>
        </Grid.ColumnDefinitions>
        <TextBox x:Name="txtNum" x:FieldModifier="private" Text="{Binding Path=NumValue}" TextChanged="TxtNum_TextChanged" FontSize="36" BorderThickness="0" VerticalAlignment="Center" Padding="5,0"/>
        <Grid Grid.Column="1">
            <Grid.RowDefinitions>
                <RowDefinition Height="30*"/>
                <RowDefinition Height="30*"/>
            </Grid.RowDefinitions>
            <Grid Background="#FF673AB7">
                <Viewbox HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Height="Auto" Width="Auto">
                    <materialDesign:PackIcon Kind="ChevronUp" Foreground="White" Height="32.941" Width="32"/>
                </Viewbox>
                <Button x:Name="cmdUp" x:FieldModifier="private" Click="CmdUp_Click" Height="Auto" BorderBrush="{x:Null}" Background="{x:Null}"/>
            </Grid>
            <Grid Grid.Row="1" Background="#FF673AB7">
                <Viewbox HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Height="Auto" Width="Auto">
                    <materialDesign:PackIcon Kind="ChevronDown" Foreground="White" Height="32.942" Width="32"/>
                </Viewbox>
                <Button x:Name="cmdDown" x:FieldModifier="private" Click="CmdDown_Click" Height="Auto" BorderBrush="{x:Null}" Background="{x:Null}"/>
            </Grid>
        </Grid>
    </Grid>
</UserControl>

TemplateNumericUpDown.cs

using System.Windows;
using System.Windows.Controls;

namespace UserControlTemplate
{
    /// <summary>
    /// Interaction logic for TemplateNumericUpDown.xaml
    /// </summary>
    public partial class TemplateNumericUpDown : UserControl
    {
        private int _numValue = 0;
        public TemplateNumericUpDown()
        {
            InitializeComponent();
            txtNum.Text = _numValue.ToString();
        }
        public int NumValue
        {
            get { return _numValue; }
            set
            {
                if (value >= 0)
                {
                    _numValue = value;
                    txtNum.Text = value.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();
        }
    }
}

En MyPageDesign.xaml, arrastrar y soltar el control de usuario creado tendrá <UserControlTemplate:TemplateNumericUpDown HorizontalAlignment="Left" Height="100" VerticalAlignment="Top" Width="100"/>

ingrese la descripción de la imagen aquí

Para obtener el valor de la plantilla, uso

string Value1 = JournalNumStart.NumValue;
string Value2 = JournalNumEnd.NumValue;

Todavía no estoy en buenas habilidades para vincular la altura del control basado en el elemento FontSize, por lo que configuré el tamaño de fuente de mi página manualmente en el control del usuario.

** Nota: - He cambiado el nombre "Archivar" a Archivar en mi programa =)

Luiey
fuente
La usabilidad de los botones arriba / abajo es horrible: son demasiado pequeños para ser útiles. Deben tener AL MENOS la misma altura que el cuadro de texto (y ser cuadrados). Sé que ocupa un poco más de espacio, pero al menos te da botones utilizables. De lo contrario, no hay ninguna razón para insertarlos.
Vincent
3

Tengo una solución ingenua pero útil. Aquí está el código:

<Grid Name="TVGrid" Background="#7F000000">  <ScrollBar Background="Black" Orientation="Vertical" Height="35" HorizontalAlignment="Left" Margin="215,254,0,0" Minimum="0" Maximum="10" LargeChange="10" Value="{Binding ElementName=channeltext2, Path=Text}" x:Name="scroll" VerticalAlignment="Top" Width="12" RenderTransformOrigin="0.5,0.5" ValueChanged="scroll_ValueChanged" >  
        <ScrollBar.RenderTransform>  
            <TransformGroup>  
                <ScaleTransform/>  
                <SkewTransform/>  
                <RotateTransform Angle="-180"/>  
                <TranslateTransform/>  
            </TransformGroup>  
        </ScrollBar.RenderTransform>  
    </ScrollBar>  
    <TextBox Name="channeltext" HorizontalContentAlignment="Center" FontSize="20"  Background="Black" Foreground="White" Height="35" HorizontalAlignment="Left" Margin="147,254,0,0" VerticalAlignment="Top" Width="53" Text="0" />  
    <TextBox Name="channeltext2" Visibility="Hidden" HorizontalContentAlignment="Center" FontSize="20"  Background="Black" Foreground="White" Height="35" HorizontalAlignment="Left" Margin="147,254,0,0" VerticalAlignment="Top" Width="53" Text="0" />  </Grid>  
Liron Harazi
fuente
3

Aquí hay otro control de código abierto que tiene muchos métodos de entrada diferentes (arrastre del mouse, rueda del mouse, teclas del cursor, edición de cuadros de texto), admite muchos tipos de datos y casos de uso:

https://github.com/Dirkster99/NumericUpDownLib

usuario8276908
fuente
1

Solo una muestra pragmática para hacer:

-Haga clic derecho en su proyecto (en Solución), seleccione "Administrar paquetes nuget ..."

-En el menú, haga clic en la pestaña Examinar busque "wpftoolkit", seleccione " Extended.Wpf.Toolkit"

-¡Instalarlo!

-Haga clic derecho en su Caja de herramientas de control de usuario , seleccione "Agregar pestaña .." y asígnele el nombre "Kit de herramientas WPF"

-Haga clic derecho en la nueva pestaña "WPF Toolkit", seleccione "Elegir elementos ..."

-En el menú, haga clic en el botón "Examinar ...", busque la carpeta DLL de nugets, seleccione todo "...\packages\Extended.Wpf.Toolkit.3.5.0\lib\net40\*.dll "

¡Ignore las advertencias sobre algunas DLL que pueden no contener controles de usuario!

Listo :)

el ambiente blanco
fuente
0

Vaya al administrador de NugetPackage de su proyecto-> Examinar y busque mahApps.Metro -> instale el paquete en su proyecto. Verá Referencia agregada: MahApps.Metro. Luego en su código XAML agregue:

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

Donde quiera usar su objeto, agregue:

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

Disfrute de la extensibilidad completa del objeto (enlaces, disparadores, etc.).

Andre
fuente