web-dev-qa-db-fra.com

Où se trouve le contrôle WPF Numeric UpDown?

Entrer dans le premier projet WPF sérieux. Il semble qu'il manque beaucoup de contrôles de base. Plus précisément, je recherche le contrôle Numeric UpDown. Y a-t-il une sortie hors du groupe que j'ai manquée? Vraiment pas envie d'écrire mon propre contrôle.

Je ne veux pas utiliser le WindowsFormHost et plop un ctl WinForm dessus. Je veux que ce soit entièrement WPF sans aucune ordure héritée.

Merci

114
AngryHacker

Utilisez simplement le contrôle IntegerUpDown dans le xtended wpf toolkit Vous pouvez l’utiliser comme ceci:

  1. Ajoutez à votre XAML l'espace de noms suivant:

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

  2. Dans votre XAML où vous voulez utiliser le contrôle:

    <xctk:IntegerUpDown Name="myUpDownControl" />

43
Stacked

J'ai fait le mien;

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

et le code derrière

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();
}
37
Michael

Ceci est un exemple de mon propre UserControl avec la capture des touches Haut et Bas.

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

Et le 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;

    }

}
15
Sonorx
<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;
        }
    }

}
7
vercin

Les réponses données sont OK. Cependant, je voulais que les boutons se masquent automatiquement lorsque la souris quitte le contrôle. Voici mon code basé sur la réponse vercin ci-dessus:

Style

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

Code

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

}
6
Ron

Utilisez VerticalScrollBar avec le contrôle TextBlock dans WPF. Dans votre code derrière, ajoutez le code suivant:

Dans le constructeur, définissez un gestionnaire d'événements pour la barre de défilement:

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

Ensuite, dans le gestionnaire d'événements, ajoutez:

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

Voici l'extrait original de mon code ... apportez les modifications nécessaires .. :)

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();
}
5
Abhinav Wase

Faites des excuses pour continuer à répondre aux questions de 9 ans.

J'ai suivi la réponse de @ Micheal et ça marche.

Je le fais en tant que UserControl où je peux glisser et déposer comme un élément de contrôle. J'utilise MaterialDesign Theme de Nuget pour obtenir l'icône Chevron et l'effet d'entraînement de bouton.

NumericUpDown de Micheal en cours d’exécution avec modification sera comme suit: -

enter image description here

Le code pour le contrôle de l'utilisateur: -

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();
        }
    }
}

Sur MyPageDesign.xaml, faites glisser le contrôle utilisateur créé avec <UserControlTemplate:TemplateNumericUpDown HorizontalAlignment="Left" Height="100" VerticalAlignment="Top" Width="100"/>

enter image description here

Pour obtenir la valeur du modèle, j'utilise

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

Je ne suis pas encore en mesure de lier la hauteur du contrôle à partir de l'élément FontSize. J'ai donc défini manuellement la taille de police de ma page dans usercontrol.

** Note: - J'ai changé le nom "Archieve" en Archive sur mon programme =)

4
Luiey

Vous pouvez utiliser le contrôle NumericUpDown pour WPF écrit par moi dans le cadre de la bibliothèque WPFControls .

4
Alex Titarenko

J'ai une solution naïve mais utile. Voici le code:

<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>  
2
Liron Harazi

Voici un autre contrôle open source comportant de nombreuses méthodes de saisie (glisser de la souris, molette de la souris, touches de curseur, édition de la zone de texte), prenant en charge de nombreux types de données et cas d'utilisation:

https://github.com/Dirkster99/NumericUpDownLib

2
user8276908

Juste un exemple pragmatique à faire:

-Cliquez à droite sur votre projet (sous Solution), sélectionnez "Gérer les paquets de nuget ..."

-Dans le menu, cliquez sur . Parcourir recherchez l'onglet "wpftoolkit", sélectionnez "Extended.Wpf.Toolkit "

- Installez-le!

-Cliquez droit dans votre boîte à outils Contrôle utilisateur , sélectionnez "Ajouter un onglet .." et nommez-le "WPF Toolkit".

-Cliquez à droite sur le nouvel onglet "WPF Toolkit", sélectionnez "Choose items ..."

-Dans le menu, cliquez sur le bouton "Parcourir ...", recherchez les nugets DLL, sélectionnez tout "...\packages\Extended.Wpf.Toolkit.3.5.0\lib\net40\*.dll "

Ignorer Les avertissements concernant certaines DLL peuvent ne pas contenir de contrôles utilisateur!

Prêt:)

1
thewhiteambit