c# - 如何将自定义控件的输出发送到文本框
问题描述
我已经为要在 WPF 应用程序中使用的虚拟键盘创建了一个按钮布局,为了使其可重用,我想我可以给它一个Target
类型的依赖属性TextBox
以将键盘的输出发送到。我也为我的键盘按钮制作了一个自定义控件,以便它们具有一个Output
属性。
将按钮的输出附加到目标 TextBox 的当前文本内容的最佳方法是什么?我应该使用事件或命令,还是其他什么?
输出窗口的 XAML:
<UserControl x:Class="Project.Views.DataInput.DataInputExample"
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:local="clr-namespace:Project.Views.DataInput"
xmlns:cc="clr-namespace:Project.CustomControls"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBox Text="{Binding ElementName=Keyboard, Path=Output}" />
<cc:Keyboard x:Name="Keyboard" Grid.Row="1" />
</Grid>
</UserControl>
XAML 用于Keyboard
:
<Style TargetType="{x:Type local:Keyboard}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:Keyboard}">
<Border ...>
<Grid x:Name="PART_Keyboard" ...>
<Grid.RowDefinitions>
...
</Grid.RowDefinitions>
<Grid x:Name="FirstRow" ...>
<Grid.ColumnDefinitions>
...
</Grid.ColumnDefinitions>
<local:KeyboardButton Output="q" Click="BtnClick" />
...
</Grid>
...
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
为Keyboard
:
public class Keyboard : Control
{
public string Output
{
get { return (string)GetValue(OutputProperty); }
set { SetValue(OutputProperty, value); }
}
public static readonly DependencyProperty OutputProperty =
DependencyProperty.Register("Output", typeof(string), typeof(Keyboard), new PropertyMetadata(""));
static Keyboard()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(Keyboard), new FrameworkPropertyMetadata(typeof(Keyboard)));
}
}
为KeyboardButton
:
public class KeyboardButton : ImageTextButton
{
public string Output
{
get { return (string)GetValue(OutputProperty); }
set { SetValue(OutputProperty, value); }
}
public static readonly DependencyProperty OutputProperty =
DependencyProperty.Register(
"Output",
typeof(string),
typeof(KeyboardButton),
new PropertyMetadata("")
);
static KeyboardButton()
{
// DefaultStyleKeyProperty.OverrideMetadata(typeof(KeyboardButton), new FrameworkPropertyMetadata(typeof(KeyboardButton)));
}
private void BtnClick(object sender, RoutedEventArgs e)
{
var button = (KeyboardButton)sender;
var keyboard = (Keyboard)(button.Parent);
keyboard.Output += button.Output;
}
}
解决方案
我会激动地说,您的虚拟键盘与其说是一个按钮,不如说是一个 ContentControl,但那是另一回事。
在您的服装虚拟键盘控件中,您创建一个属性:
public string EnteredText {get; private set; }
在您的虚拟键盘中,您确保此属性始终包含当前输入的文本。当你有一个窗口时,你想在文本框中显示输入的文本,可以通过以下方式完成:
<local:VirtualKeyboard x:Name="MyVirtualKeyboard" />
<TextBox Text="{Binding ElementName=MyVirtualKeyboard, Path=EnteredText}" />
然后通过绑定魔法,文本框将包含用户输入的文本。您可以使用许多其他类型的控件。例如,一个 TextBlock 将是一个显而易见的候选者。
因为 KeyboardButtons 被放置在虚拟键盘控件中,我们需要一个辅助方法,这在许多其他情况下也很方便:
public static P FindVisualParent<P>(DependencyObject Dep) where P : DependencyObject
{
while (Dep != null)
{
if ((Dep is Visual) || (Dep is System.Windows.Media.Media3D.Visual3D))
{
if (Dep is P) return (Dep as P);
Dep = VisualTreeHelper.GetParent(Dep);
}
else
{
Dep = LogicalTreeHelper.GetParent(Dep);
}
}
return (null);
}
然后在 KeyboardButton 用户控件中使用此方法:
public override void OnApplyTemplate()
{
// Base call
base.OnApplyTemplate();
// Get the virtual keyboard control
this.virtualKeyboard = FindVisualParent<VirtualKeyboard>(this);
// Set the click event
this.Click += (s,e) => { this.virtualKeyboard.EnteredText += this.Output; };
}
并且在 KeyboardButton 控件中也有这个定义为成员变量:
private VirtualKeyboard virtualKeyboard;
推荐阅读
- python - 如何在 Python 中打印形状?
- javascript - Reactjs 中的 API 调用
- python - Run python script in jenkins
- python - 按顺序组织列表中的元素
- c++ - C++ 只读取一行字符
- sql-server - 如何从ms sql中的变量中删除最后一个值
- python - 烧瓶应用程序中超出了Python最大递归深度
- python - dash 应用程序拒绝启动:“127.0.0.1 拒绝连接。”
- javascript - 如何使用javascript从自动完成文本框中获取价值
- vue.js - Vuejs中的谷歌地图矩形多边形