行为的好处
可以把复杂的界面逻辑抽象出去,让xaml的界面设计更简单,更清爽
1.安装包
Microsoft.Xaml.Behaviors.Wpf
2.简单实现拖动效果
<Border Width="100"
Height="100"
Background="Red">
<i:Interaction.Behaviors>
<i:MouseDragElementBehavior />
</i:Interaction.Behaviors>
</Border>
3.简单自定义一个行为
定义一个情况文本框的行为
c#
public class ClearTextBoxBehavior : Behavior<Button>
{
// 定义依赖属性,用于绑定目标 TextBox
public TextBox TargetTextBox
{
get => (TextBox)GetValue(TargetTextBoxProperty);
set => SetValue(TargetTextBoxProperty, value);
}
public static readonly DependencyProperty TargetTextBoxProperty =
DependencyProperty.Register(
nameof(TargetTextBox),
typeof(TextBox),
typeof(ClearTextBoxBehavior),
new PropertyMetadata(null));
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.Click += OnButtonClick; // 订阅按钮点击事件
}
protected override void OnDetaching()
{
base.OnDetaching();
AssociatedObject.Click -= OnButtonClick; // 清理事件
}
private void OnButtonClick(object sender, RoutedEventArgs e)
{
TargetTextBox?.SetCurrentValue(TextBox.TextProperty, string.Empty); // 清空文本框
TargetTextBox?.Focus(); // 可选:清空后聚焦文本框
}
}
引入
xaml
xmlns:local1="clr-namespace:TestBinding.Behaviors"
xaml
<StackPanel>
<TextBox Height="30"
Name="txtInput"></TextBox>
<Button Height="30"
>
<i:Interaction.Behaviors>
<local1:ClearTextBoxBehavior TargetTextBox="{Binding ElementName=txtInput}" />
</i:Interaction.Behaviors>
</Button>
</StackPanel>
一个可以按上键增加值下键减少值的TextBox
c#
public class NumericUpDownBehavior : Behavior<TextBox>
{
// 定义依赖属性:最小值、最大值、步长
public double Min
{
get => (double)GetValue(MinProperty);
set => SetValue(MinProperty, value);
}
public static readonly DependencyProperty MinProperty =
DependencyProperty.Register(
nameof(Min),
typeof(double),
typeof(NumericUpDownBehavior),
new PropertyMetadata(double.MinValue)); // 默认无下限
public double Max
{
get => (double)GetValue(MaxProperty);
set => SetValue(MaxProperty, value);
}
public static readonly DependencyProperty MaxProperty =
DependencyProperty.Register(
nameof(Max),
typeof(double),
typeof(NumericUpDownBehavior),
new PropertyMetadata(double.MaxValue)); // 默认无上限
public double Step
{
get => (double)GetValue(StepProperty);
set => SetValue(StepProperty, value);
}
public static readonly DependencyProperty StepProperty =
DependencyProperty.Register(
nameof(Step),
typeof(double),
typeof(NumericUpDownBehavior),
new PropertyMetadata(1.0)); // 默认步长=1
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.PreviewKeyDown += OnKeyDown;
AssociatedObject.LostFocus += OnLostFocus;
}
protected override void OnDetaching()
{
base.OnDetaching();
AssociatedObject.PreviewKeyDown -= OnKeyDown;
AssociatedObject.LostFocus -= OnLostFocus;
}
private void OnKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Up || e.Key == Key.Down)
{
// 解析当前值(兼容不同文化的小数点)
var text = AssociatedObject.Text.Replace(",", "."); // 统一小数点格式
if (!double.TryParse(text, NumberStyles.Any, CultureInfo.InvariantCulture, out var currentValue))
currentValue = 0;
// 计算新值并限制范围
var step = e.Key == Key.Up ? Step : -Step;
currentValue = Math.Clamp(currentValue + step, Min, Max);
// 更新文本框
AssociatedObject.Text = currentValue.ToString(CultureInfo.InvariantCulture);
AssociatedObject.CaretIndex = AssociatedObject.Text.Length;
e.Handled = true;
}
}
private void OnLostFocus(object sender, RoutedEventArgs e)
{
// 失去焦点时格式化并重新检查范围
if (double.TryParse(AssociatedObject.Text, NumberStyles.Any, CultureInfo.InvariantCulture, out var value))
{
var clampedValue = Math.Clamp(value, Min, Max);
AssociatedObject.Text = clampedValue.ToString(CultureInfo.InvariantCulture);
}
else
{
AssociatedObject.Text = Min.ToString(CultureInfo.InvariantCulture); // 非法输入时重置为最小值
}
}
}
输入时可以定制最大值、最小值、步长
<TextBox Height="30"
Name="txtInput">
<i:Interaction.Behaviors>
<local1:NumericUpDownBehavior Max="100" Min="0" Step="3" />
</i:Interaction.Behaviors>
</TextBox>