WPF中Behaviors
行为的好处
可以把复杂的界面逻辑抽象出去,让xaml的界面设计更简单,更清爽
1.安装包
Microsoft.Xaml.Behaviors.Wpf
2.简单实现拖动效果
<Border Width="100"Height="100"Background="Red"><i:Interaction.Behaviors><i:MouseDragElementBehavior /></i:Interaction.Behaviors>
</Border>
3.简单自定义一个行为
定义一个情况文本框的行为
public class ClearTextBoxBehavior : Behavior<Button>
{// 定义依赖属性,用于绑定目标 TextBoxpublic 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(); // 可选:清空后聚焦文本框}
}
引入
xmlns:local1="clr-namespace:TestBinding.Behaviors"
<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
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)); // 默认步长=1protected 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>