最好的答案是附加依赖属性的形式。用法:
xmlns:e="clr-namespace:Extensions"
<TextBox e:TextBoxExtensions.IsEditableOnlyOnDoubleClick="True"/>
#nullable enable
namespace Extensions;
public static class TextBoxExtensions
{
#region IsEditableOnlyOnDoubleClick
public static readonly DependencyProperty IsEditableOnlyOnDoubleClickProperty =
DependencyProperty.RegisterAttached(
nameof(IsEditableOnlyOnDoubleClickProperty).Replace("Property", string.Empty),
typeof(bool),
typeof(TextBoxExtensions),
new PropertyMetadata(false, OnIsEditableOnlyOnDoubleClickChanged));
[AttachedPropertyBrowsableForType(typeof(TextBox))]
public static bool GetIsEditableOnlyOnDoubleClick(DependencyObject element)
{
return (bool)element.GetValue(IsEditableOnlyOnDoubleClickProperty);
}
public static void SetIsEditableOnlyOnDoubleClick(DependencyObject element, bool value)
{
element.SetValue(IsEditableOnlyOnDoubleClickProperty, value);
}
private static void OnIsEditableOnlyOnDoubleClickChanged(
DependencyObject element,
DependencyPropertyChangedEventArgs args)
{
if (element is not TextBox textBox)
{
throw new ArgumentException($"{nameof(element)} should be {nameof(TextBox)}.");
}
if (args.OldValue is true)
{
textBox.MouseDoubleClick -= TextBox_MouseDoubleClick;
textBox.LostFocus -= TextBox_LostFocus;
textBox.IsReadOnly = false;
}
if (args.NewValue is true)
{
textBox.MouseDoubleClick += TextBox_MouseDoubleClick;
textBox.LostFocus += TextBox_LostFocus;
textBox.IsReadOnly = true;
}
}
private static void TextBox_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
if (sender is not TextBox textBox)
{
return;
}
textBox.IsReadOnly = false;
textBox.SelectAll();
}
private static void TextBox_LostFocus(object sender, RoutedEventArgs e)
{
if (sender is not TextBox textBox)
{
return;
}
textBox.IsReadOnly = true;
}
#endregion
}