WPF TextBox 扩展无法使用 MahApps TextBoxHelper
WPF TextBox Extension unable to use MahApps TextBoxHelper
我有一个扩展的 wpf 文本框,我想使用 MahApps TextBoxHelper 添加水印。使用常规文本框效果很好,但当我尝试用我的扩展文本框 TouchTextBox
替换它们时,水印与 Metro 风格一起消失了。我的扩展文本框旨在与自定义触摸键盘一起使用,并且它有许多用于处理此功能的事件:
XAML:
<TextBox x:Class="MyNamespaceHERE.TouchTextBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
xmlns:local="clr-namespace:MyNamespaceHERE"
mc:Ignorable="d"
GotFocus="TouchTextBox_GotFocus"
LostFocus="TouchTextBox_LostFocus">
</TextBox>
隐藏代码:
public partial class TouchTextBox : TextBox
{
public TouchTextBox()
{
InitializeComponent();
}
private void TouchTextBox_GotFocus(object sender, RoutedEventArgs e)
{
StaticEvents.OnShowTouchKeyboard(sender, e);
StaticEvents.TouchKeyboardKeyTouch += StaticEvents_TouchKeyboardKeyTouch;
StaticEvents.TouchKeyboardSpaceTouch += StaticEvents_TouchKeyboardSpaceTouch;
StaticEvents.TouchKeyboardBackspaceTouch += StaticEvents_TouchKeyboardBackspaceTouch;
}
private void StaticEvents_TouchKeyboardBackspaceTouch(object sender, EventArgs e)
{
int i = CaretIndex;
if (CaretIndex == 0) return;
Text = Text.Remove(CaretIndex - 1, 1);
CaretIndex = i - 1;
}
private void StaticEvents_TouchKeyboardSpaceTouch(object sender, EventArgs e)
{
int i = CaretIndex;
Text = Text.Insert(CaretIndex, " ");
CaretIndex = i + 1;
}
private void StaticEvents_TouchKeyboardKeyTouch(object sender, EventArgs e)
{
int i = CaretIndex;
string t = (sender as Button).Content.ToString();
Text = Text.Insert(CaretIndex, t);
CaretIndex = i + 1;
}
private void TouchTextBox_LostFocus(object sender, RoutedEventArgs e)
{
StaticEvents.OnHideTouchKeyboard(sender, e);
StaticEvents.TouchKeyboardKeyTouch -= StaticEvents_TouchKeyboardKeyTouch;
StaticEvents.TouchKeyboardSpaceTouch -= StaticEvents_TouchKeyboardSpaceTouch;
StaticEvents.TouchKeyboardBackspaceTouch -= StaticEvents_TouchKeyboardBackspaceTouch;
}
}
我遵循了我在这个解决方案 中找到的建议,但到目前为止还没有解决问题。根据解决方案,我需要添加一个基于 TextBox 的样式,所以这是我的资源字典中的内容:
<Style TargetType="local:TouchTextBox" BasedOn="{StaticResource {x:Type TextBox}}" x:Key="TouchTextBoxStyle"/>
我将此样式添加到我的 TouchTextBox 控件的每个实例中,使它们看起来像这样:
<local:TouchTextBox x:Name="UsernameTextBox" Controls:TextBoxHelper.Watermark="Username" Width="200" Text="{Binding Username}" Style="{StaticResource TouchTextBoxStyle}"/>
<local:TouchTextBox x:Name="PasswordTextBox" Controls:TextBoxHelper.Watermark="Password" Width="200" Margin="0,30,0,0" Text="{Binding Password}" Style="{StaticResource TouchTextBoxStyle}"/>
到目前为止还没有运气。如何使用自定义 TouchTextBox 用户控件恢复 MahApps 的 TextBoxHelper 的所有强大功能?非常感谢您提供的任何指导。
编辑:
我采纳了 Joel Lucsy 的建议并实施了 TouchTextBoxHelper
class 来处理 DependencyProperty
我的事件处理:
public class TouchTextBoxHelper : DependencyObject
{
public static readonly DependencyProperty IsTouchKeyboardTargetProperty = DependencyProperty.Register("IsTouchKeyboardTarget", typeof(bool), typeof(TouchTextBoxHelper), new FrameworkPropertyMetadata(false, IsTouchKeyboardTargetChanged));
[AttachedPropertyBrowsableForType(typeof(TextBox))]
public static bool GetIsTouchKeyboardTargetEnabled(DependencyObject obj)
{
return (bool)obj.GetValue(IsTouchKeyboardTargetProperty);
}
[AttachedPropertyBrowsableForType(typeof(TextBox))]
public static void SetIsTouchKeyboardTargetEnabled(DependencyObject obj, bool value)
{
obj.SetValue(IsTouchKeyboardTargetProperty, value);
TextBox tb = obj as TextBox;
if (tb == null) return;
if (value)
{
tb.GotFocus += TextBoxBaseGotFocus;
tb.LostFocus += TextBoxBaseLostFocus;
}
else
{
tb.GotFocus -= TextBoxBaseGotFocus;
tb.LostFocus -= TextBoxBaseLostFocus;
}
}
private static void IsTouchKeyboardTargetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var tb = d as TextBox;
if (null == tb)
{
throw new InvalidOperationException("The property 'IsTouchKeyboardTarget' may only be set on TextBox elements.");
}
if (e.OldValue != e.NewValue)
{
//tb.SetValue(SpellCheck.IsEnabledProperty, (bool)e.NewValue);
if ((bool)e.NewValue)
{
tb.GotFocus += TextBoxBaseGotFocus;
tb.LostFocus += TextBoxBaseLostFocus;
}
else
{
tb.GotFocus -= TextBoxBaseGotFocus;
tb.LostFocus -= TextBoxBaseLostFocus;
}
}
}
private static void TextBoxBaseGotFocus(object sender, RoutedEventArgs e)
{
TouchTextBoxEvents.tb = sender as TextBox;
StaticEvents.OnShowTouchKeyboard(sender, e);
StaticEvents.TouchKeyboardKeyTouch += TouchTextBoxEvents.StaticEvents_TouchKeyboardKeyTouch;
StaticEvents.TouchKeyboardSpaceTouch += TouchTextBoxEvents.StaticEvents_TouchKeyboardSpaceTouch;
StaticEvents.TouchKeyboardBackspaceTouch += TouchTextBoxEvents.StaticEvents_TouchKeyboardBackspaceTouch;
}
private static void TextBoxBaseLostFocus(object sender, RoutedEventArgs e)
{
StaticEvents.OnHideTouchKeyboard(sender, e);
StaticEvents.TouchKeyboardKeyTouch -= TouchTextBoxEvents.StaticEvents_TouchKeyboardKeyTouch;
StaticEvents.TouchKeyboardSpaceTouch -= TouchTextBoxEvents.StaticEvents_TouchKeyboardSpaceTouch;
StaticEvents.TouchKeyboardBackspaceTouch -= TouchTextBoxEvents.StaticEvents_TouchKeyboardBackspaceTouch;
}
}
public class TouchTextBoxEvents
{
public static TextBox tb = null;
public static void StaticEvents_TouchKeyboardKeyTouch(object sender, EventArgs e)
{
int i = tb.CaretIndex;
string t = (sender as Button).Content.ToString();
tb.Text = tb.Text.Insert(tb.CaretIndex, t);
tb.CaretIndex = i + 1;
}
public static void StaticEvents_TouchKeyboardBackspaceTouch(object sender, EventArgs e)
{
int i = tb.CaretIndex;
if (tb.CaretIndex == 0) return;
tb.Text = tb.Text.Remove(tb.CaretIndex - 1, 1);
tb.CaretIndex = i - 1;
}
public static void StaticEvents_TouchKeyboardSpaceTouch(object sender, EventArgs e)
{
int i = tb.CaretIndex;
tb.Text = tb.Text.Insert(tb.CaretIndex, " ");
tb.CaretIndex = i + 1;
}
}
有点吓人,但确实有效!
我认为您需要将此 Attached Properties
添加到 TextBox
以显示水印。
controls:TextBoxHelper.Watermark="My Watermark"
controls:TextBoxHelper.UseFloatingWatermark="True" // If Needed.
完整代码 TextBox
.
<TextBox Height="40" Width="125" MaxLength="15"
controls:TextBoxHelper.Watermark="My Watermark"
controls:TextBoxHelper.UseFloatingWatermark="True"/>
希望对您有所帮助。
与其创建自定义控件,不如创建一个 DependencyProperty,类似于 TextBoxHelper 将事件添加到普通 TextBox 的方式。这也将消除对样式的需求。
我有一个扩展的 wpf 文本框,我想使用 MahApps TextBoxHelper 添加水印。使用常规文本框效果很好,但当我尝试用我的扩展文本框 TouchTextBox
替换它们时,水印与 Metro 风格一起消失了。我的扩展文本框旨在与自定义触摸键盘一起使用,并且它有许多用于处理此功能的事件:
XAML:
<TextBox x:Class="MyNamespaceHERE.TouchTextBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
xmlns:local="clr-namespace:MyNamespaceHERE"
mc:Ignorable="d"
GotFocus="TouchTextBox_GotFocus"
LostFocus="TouchTextBox_LostFocus">
</TextBox>
隐藏代码:
public partial class TouchTextBox : TextBox
{
public TouchTextBox()
{
InitializeComponent();
}
private void TouchTextBox_GotFocus(object sender, RoutedEventArgs e)
{
StaticEvents.OnShowTouchKeyboard(sender, e);
StaticEvents.TouchKeyboardKeyTouch += StaticEvents_TouchKeyboardKeyTouch;
StaticEvents.TouchKeyboardSpaceTouch += StaticEvents_TouchKeyboardSpaceTouch;
StaticEvents.TouchKeyboardBackspaceTouch += StaticEvents_TouchKeyboardBackspaceTouch;
}
private void StaticEvents_TouchKeyboardBackspaceTouch(object sender, EventArgs e)
{
int i = CaretIndex;
if (CaretIndex == 0) return;
Text = Text.Remove(CaretIndex - 1, 1);
CaretIndex = i - 1;
}
private void StaticEvents_TouchKeyboardSpaceTouch(object sender, EventArgs e)
{
int i = CaretIndex;
Text = Text.Insert(CaretIndex, " ");
CaretIndex = i + 1;
}
private void StaticEvents_TouchKeyboardKeyTouch(object sender, EventArgs e)
{
int i = CaretIndex;
string t = (sender as Button).Content.ToString();
Text = Text.Insert(CaretIndex, t);
CaretIndex = i + 1;
}
private void TouchTextBox_LostFocus(object sender, RoutedEventArgs e)
{
StaticEvents.OnHideTouchKeyboard(sender, e);
StaticEvents.TouchKeyboardKeyTouch -= StaticEvents_TouchKeyboardKeyTouch;
StaticEvents.TouchKeyboardSpaceTouch -= StaticEvents_TouchKeyboardSpaceTouch;
StaticEvents.TouchKeyboardBackspaceTouch -= StaticEvents_TouchKeyboardBackspaceTouch;
}
}
我遵循了我在这个解决方案
<Style TargetType="local:TouchTextBox" BasedOn="{StaticResource {x:Type TextBox}}" x:Key="TouchTextBoxStyle"/>
我将此样式添加到我的 TouchTextBox 控件的每个实例中,使它们看起来像这样:
<local:TouchTextBox x:Name="UsernameTextBox" Controls:TextBoxHelper.Watermark="Username" Width="200" Text="{Binding Username}" Style="{StaticResource TouchTextBoxStyle}"/>
<local:TouchTextBox x:Name="PasswordTextBox" Controls:TextBoxHelper.Watermark="Password" Width="200" Margin="0,30,0,0" Text="{Binding Password}" Style="{StaticResource TouchTextBoxStyle}"/>
到目前为止还没有运气。如何使用自定义 TouchTextBox 用户控件恢复 MahApps 的 TextBoxHelper 的所有强大功能?非常感谢您提供的任何指导。
编辑:
我采纳了 Joel Lucsy 的建议并实施了 TouchTextBoxHelper
class 来处理 DependencyProperty
我的事件处理:
public class TouchTextBoxHelper : DependencyObject
{
public static readonly DependencyProperty IsTouchKeyboardTargetProperty = DependencyProperty.Register("IsTouchKeyboardTarget", typeof(bool), typeof(TouchTextBoxHelper), new FrameworkPropertyMetadata(false, IsTouchKeyboardTargetChanged));
[AttachedPropertyBrowsableForType(typeof(TextBox))]
public static bool GetIsTouchKeyboardTargetEnabled(DependencyObject obj)
{
return (bool)obj.GetValue(IsTouchKeyboardTargetProperty);
}
[AttachedPropertyBrowsableForType(typeof(TextBox))]
public static void SetIsTouchKeyboardTargetEnabled(DependencyObject obj, bool value)
{
obj.SetValue(IsTouchKeyboardTargetProperty, value);
TextBox tb = obj as TextBox;
if (tb == null) return;
if (value)
{
tb.GotFocus += TextBoxBaseGotFocus;
tb.LostFocus += TextBoxBaseLostFocus;
}
else
{
tb.GotFocus -= TextBoxBaseGotFocus;
tb.LostFocus -= TextBoxBaseLostFocus;
}
}
private static void IsTouchKeyboardTargetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var tb = d as TextBox;
if (null == tb)
{
throw new InvalidOperationException("The property 'IsTouchKeyboardTarget' may only be set on TextBox elements.");
}
if (e.OldValue != e.NewValue)
{
//tb.SetValue(SpellCheck.IsEnabledProperty, (bool)e.NewValue);
if ((bool)e.NewValue)
{
tb.GotFocus += TextBoxBaseGotFocus;
tb.LostFocus += TextBoxBaseLostFocus;
}
else
{
tb.GotFocus -= TextBoxBaseGotFocus;
tb.LostFocus -= TextBoxBaseLostFocus;
}
}
}
private static void TextBoxBaseGotFocus(object sender, RoutedEventArgs e)
{
TouchTextBoxEvents.tb = sender as TextBox;
StaticEvents.OnShowTouchKeyboard(sender, e);
StaticEvents.TouchKeyboardKeyTouch += TouchTextBoxEvents.StaticEvents_TouchKeyboardKeyTouch;
StaticEvents.TouchKeyboardSpaceTouch += TouchTextBoxEvents.StaticEvents_TouchKeyboardSpaceTouch;
StaticEvents.TouchKeyboardBackspaceTouch += TouchTextBoxEvents.StaticEvents_TouchKeyboardBackspaceTouch;
}
private static void TextBoxBaseLostFocus(object sender, RoutedEventArgs e)
{
StaticEvents.OnHideTouchKeyboard(sender, e);
StaticEvents.TouchKeyboardKeyTouch -= TouchTextBoxEvents.StaticEvents_TouchKeyboardKeyTouch;
StaticEvents.TouchKeyboardSpaceTouch -= TouchTextBoxEvents.StaticEvents_TouchKeyboardSpaceTouch;
StaticEvents.TouchKeyboardBackspaceTouch -= TouchTextBoxEvents.StaticEvents_TouchKeyboardBackspaceTouch;
}
}
public class TouchTextBoxEvents
{
public static TextBox tb = null;
public static void StaticEvents_TouchKeyboardKeyTouch(object sender, EventArgs e)
{
int i = tb.CaretIndex;
string t = (sender as Button).Content.ToString();
tb.Text = tb.Text.Insert(tb.CaretIndex, t);
tb.CaretIndex = i + 1;
}
public static void StaticEvents_TouchKeyboardBackspaceTouch(object sender, EventArgs e)
{
int i = tb.CaretIndex;
if (tb.CaretIndex == 0) return;
tb.Text = tb.Text.Remove(tb.CaretIndex - 1, 1);
tb.CaretIndex = i - 1;
}
public static void StaticEvents_TouchKeyboardSpaceTouch(object sender, EventArgs e)
{
int i = tb.CaretIndex;
tb.Text = tb.Text.Insert(tb.CaretIndex, " ");
tb.CaretIndex = i + 1;
}
}
有点吓人,但确实有效!
我认为您需要将此 Attached Properties
添加到 TextBox
以显示水印。
controls:TextBoxHelper.Watermark="My Watermark"
controls:TextBoxHelper.UseFloatingWatermark="True" // If Needed.
完整代码 TextBox
.
<TextBox Height="40" Width="125" MaxLength="15"
controls:TextBoxHelper.Watermark="My Watermark"
controls:TextBoxHelper.UseFloatingWatermark="True"/>
希望对您有所帮助。
与其创建自定义控件,不如创建一个 DependencyProperty,类似于 TextBoxHelper 将事件添加到普通 TextBox 的方式。这也将消除对样式的需求。