我们使用附加属性来实现,依赖属性也可以实现,原理一样
如图
xmal
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TextBoxTest">
<local:BoolToVisibleConverter x:Key="BoolToVisibleConverter"/>
<Style TargetType="{x:Type TextBox}" >
<Setter Property="BorderBrush"
Value="LightGray"/>
<Setter Property="BorderThickness"
Value="1"/>
<Setter Property="Foreground"
Value="#3E3E3E" />
<Setter Property="Background"
Value="White"/>
<Setter Property="FontSize" Value="15"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Border x:Name="border"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
CornerRadius="{Binding Path=(local:TextBoxHelper.CornerRadius),RelativeSource={RelativeSource AncestorType=TextBox}, Mode=OneWay}"
SnapsToDevicePixels="True">
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ScrollViewer x:Name="PART_ContentHost"
Focusable="false"
HorizontalScrollBarVisibility="Hidden"
VerticalScrollBarVisibility="Hidden"/>
<Grid Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid>
<RepeatButton Width="25"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Name="PART_BtnAdd"
Visibility="{Binding Path=(local:TextBoxHelper.IsAddButtonVisible),RelativeSource={RelativeSource AncestorType=TextBox}, Converter={StaticResource BoolToVisibleConverter}}">
<RepeatButton.Content>
<Image Source="上箭头1.png"></Image>
</RepeatButton.Content>
</RepeatButton>
</Grid>
<Grid Grid.Row="1">
<RepeatButton Width="25"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Name="PART_BtnRemove"
Visibility="{Binding Path=(local:TextBoxHelper.IsRemoveButtonVisible),RelativeSource={RelativeSource AncestorType=TextBox}, Converter={StaticResource BoolToVisibleConverter}}" >
<RepeatButton.Content>
<Image Source="下箭头1.png"></Image>
</RepeatButton.Content>
</RepeatButton>
</Grid>
</Grid>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled"
Value="False">
<Setter Property="Opacity"
Value="0.4"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
CS,定义附加属性
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
namespace TextBoxTest
{
public class BoolToVisibleConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return (bool)value ? Visibility.Visible : Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return DependencyProperty.UnsetValue;
}
}
/// <summary>
/// 测试附加属性
/// </summary>
public class TextBoxHelper
{
public static bool GetIsAddButtonVisible(DependencyObject obj)
{
return (bool)obj.GetValue(IsAddButtonVisibleProperty);
}
public static void SetIsAddButtonVisible(DependencyObject obj, bool value)
{
obj.SetValue(IsAddButtonVisibleProperty, value);
}
// Using a DependencyProperty as the backing store for MyProperty. This enables animation, styling, binding, etc...
public static readonly DependencyProperty IsAddButtonVisibleProperty =
DependencyProperty.RegisterAttached("IsAddButtonVisible", typeof(bool), typeof(TextBoxHelper), new PropertyMetadata(OnTextChanged));
public static bool GetIsRemoveButtonVisible(DependencyObject obj)
{
return (bool)obj.GetValue(IsRemoveButtonVisibleProperty);
}
public static void SetIsRemoveButtonVisible(DependencyObject obj, bool value)
{
obj.SetValue(IsRemoveButtonVisibleProperty, value);
}
public static readonly DependencyProperty IsRemoveButtonVisibleProperty =
DependencyProperty.RegisterAttached("IsRemoveButtonVisible", typeof(bool), typeof(TextBoxHelper), new PropertyMetadata(OnTextChanged));
private static void OnTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var textbox = d as TextBox;
if ((bool)e.NewValue == true)
{
textbox.MouseWheel += Textbox_MouseWheel;
}
else
{
textbox.MouseWheel -= Textbox_MouseWheel;
}
textbox.RemoveHandler(Button.ClickEvent, new RoutedEventHandler(ButtonClicked));
textbox.AddHandler(Button.ClickEvent, new RoutedEventHandler(ButtonClicked));
}
/// <summary>
/// 鼠标滚轮
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void Textbox_MouseWheel(object sender, System.Windows.Input.MouseWheelEventArgs e)
{
var textbox = sender as TextBox;
double temp;
bool result = double.TryParse(textbox.Text, out temp);
if (result == true)
{
if (e.Delta > 0)
{
textbox.Text = (temp + 1).ToString();
}
else
{
textbox.Text = (temp - 1).ToString();
}
textbox.Select(textbox.Text.Length, 0);//光标设置到文本尾部
}
}
private static void ButtonClicked(object sender, RoutedEventArgs e)
{
var button = e.OriginalSource as RepeatButton;
if (button == null)
return;
var textbox = sender as TextBox;
if (textbox == null)
return;
double temp;
bool result = double.TryParse(textbox.Text, out temp);
if (result == true)
{
if (button.Name == "PART_BtnAdd")
{
textbox.Text = (temp + 1).ToString();
}
else
{
textbox.Text = (temp - 1).ToString();
}
textbox.Focus();
textbox.Select(textbox.Text.Length, 0);
}
}
}
}
使用
<TextBox Width="100" Height="25"
local:TextBoxHelper.IsAddButtonVisible="True"
local:TextBoxHelper.IsRemoveButtonVisible="True"></TextBox>
demo
https://github.com/danyueming/AddDeleteTextBox/tree/master/TextBoxTest
来源:CSDN
作者:淡月明
链接:https://blog.csdn.net/sinat_31608641/article/details/103461238