첫 번째 심각한 WPF 프로젝트 시작. 기본 컨트롤이 많이 누락 된 것 같습니다. 특히 Numeric UpDown 컨트롤을 찾고 있습니다. 내가 놓친 대역 외 릴리스가 있었습니까? 내 자신의 컨트롤을 작성하고 싶지 않습니다.
WindowsFormHost를 사용하고 WinForm ctl을 사용하고 싶지 않습니다. 레거시 정크없이 완전히 WPF가되기를 바랍니다.
감사
답변
xtended wpf 툴킷 의 IntegerUpDown
컨트롤을
사용하면됩니다. 다음과 같이 사용할 수 있습니다.
-
XAML에 다음 네임 스페이스를 추가합니다.
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
-
컨트롤을 사용하려는 XAML에서 다음을 사용합니다.
<xctk:IntegerUpDown Name="myUpDownControl" />
답변
나는 내 자신을 만들었다.
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>
그리고 뒤에있는 코드
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();
}
답변
이것은 Up 및 Down 키 캐치를 사용하는 내 자신의 UserControl의 예입니다.
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>
그리고 코드 :
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;
}
}
답변
<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 답변을 기반으로 한 내 코드는 다음과 같습니다 .
스타일
<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>
암호
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;
}
}
}
답변
WPF VerticalScrollBar
의 TextBlock
컨트롤 과 함께 사용 합니다 . 코드 뒤에 다음 코드를 추가하십시오.
생성자에서 스크롤바에 대한 이벤트 핸들러를 정의합니다.
scrollBar1.ValueChanged += new RoutedPropertyChangedEventHandler<double>(scrollBar1_ValueChanged);
scrollBar1.Minimum = 0;
scrollBar1.Maximum = 1;
scrollBar1.SmallChange = 0.1;
그런 다음 이벤트 처리기에서 다음을 추가합니다.
void scrollBar1_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
FteHolderText.Text = scrollBar1.Value.ToString();
}
다음은 내 코드의 원본 스 니펫입니다. 필요한 사항을 변경합니다 .. 🙂
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();
}