如何在单击关闭文本框时更新文本框的绑定
本文关键字:文本 绑定 更新 单击 | 更新日期: 2023-09-27 18:09:16
在我的应用程序中,我有一个Usercontrol,它代表一个对象的一些配置。其中是一个Texblock,其中包含了所述对象的名称。我希望能够点击这个Textblock并把它变成一个文本框,这样你就可以编辑名字了。
我希望它有以下3个行为
- 在按enter键时设置ViewModel中的值
- 当键盘变得可见时获得键盘焦点
- 设置当鼠标在文本框外点击时ViewModel中的值(就像组合框一样)
,我目前被困在3。我怎么能让我的文本框满足要求3 -点击文本框设置值我已经实现了一些附件行为,使其他2个工作,但不能让鼠标一个工作。
我已经尝试了以下
- 增加了PreviewMouseDown事件-这似乎只有当鼠标按下在文本框 时才会被检测到
- 添加PreviewMouseDown甚至在用户控制-这似乎得到击中,即使当文本框被点击。它也不是我窗口内唯一的用户控件,所以它不会在更大的范围内工作。
- 添加了previewmousedownoutside ecapturedelement -但永远不能让它触发
- 同时失去对UpdateSourceTrigger和作为一个事件的关注-这只在你点击一个不同的输入字段而不是直接点击 时才有效。
文本框的代码如下所示。
<TextBox x:Name="text" VerticalAlignment="Center"
Margin="5,2,0,0"
Text="{Binding Name, Mode=TwoWay}"
Visibility="{Binding IsEditingName, Converter={StaticResource VisConverter}, FallbackValue=Collapsed}"
b:FocusBehaviours.ShouldFocusWhenVisible="True"
b:InputBehaviours.UpdatePropertySourceWhenEnterPressed="TextBox.Text"/>
我看过无数的SO帖子,似乎没有一个能帮助我解决这个问题,他们都建议把它添加到窗口/用户控制,我不能这样做。
我终于找到了解决办法。
基本上,我在文本框的OnGotFocus后面绑定了一个事件。当它碰到这个方法时,它会给用户控件添加一个MouseDown和MouseLeave事件。所以当你点击usercontrol的任意位置时它会更新文本框的内容如果你离开了用户控件的边界,那么你想把鼠标向下事件移到窗口本身。类似地,当你移动回用户控件时,你想要删除窗口上的鼠标下降事件,或者当你离开后单击回文本框时,它会设置值。
我在这里添加了我的代码,希望它将清楚谁可能有类似的问题。
我相信一定有比使用后面的代码更好的方法,但我不认为我在这里违反了MVVM原则,所以我认为我是安全的。
private void View_OnMouseDown(object sender, MouseButtonEventArgs e)
{
updateTextbox();
}
private void View_OnMouseLeave(object sender, MouseEventArgs e)
{
Window parentWindow = Window.GetWindow(this);
if (parentWindow != null)
{
Mouse.AddPreviewMouseDownHandler(parentWindow, ParentWindow_OnMouseDown);
}
}
private void View_OnMouseEnter(object sender, MouseEventArgs e)
{
Window parentWindow = Window.GetWindow(this);
if (parentWindow != null)
{
Mouse.RemovePreviewMouseDownHandler(parentWindow, ParentWindow_OnMouseDown);
}
}
private void ParentWindow_OnMouseDown(object sender, MouseButtonEventArgs mouseButtonEventArgs)
{
Window parentWindow = Window.GetWindow(this);
if (parentWindow != null)
{
Mouse.RemovePreviewMouseDownHandler(parentWindow, ParentWindow_OnMouseDown);
}
updateTextbox();
}
private void updateTextbox()
{
Keyboard.Focus(this);
}
private void Text_OnGotFocus(object sender, RoutedEventArgs e)
{
MouseDown += View_OnMouseDown;
MouseLeave += View_OnMouseLeave;
MouseEnter += View_OnMouseEnter;
}
private void Text_OnLostFocus(object sender, RoutedEventArgs e)
{
BindingOperations.GetBindingExpression(text, TextBox.TextProperty).UpdateSource();
MouseDown -= View_OnMouseDown;
MouseLeave -= View_OnMouseLeave;
MouseEnter -= View_OnMouseEnter;
}
我在WPF 窗口为内置的TextBox
这样做,以便在用户点击外部时做一些事情。该方法可以很容易地应用于WPF/UWP的Window
或Page
。
// In your `XxxWindow.xaml.cs`(or corresponding class in VB):
public partial class XxxWindow : Window {
...
// The event handler delegate for handling click outsides a TextBox.
private readonly MouseButtonEventHandler windowWideMouseButtonEventHandler;
// Add something in the constructor or any initialization methods.
public MainWindow() {
...
// Initialize the handler.
windowWideMouseButtonEventHandler = new MouseButtonEventHandler(OnWindowWideMouseEvent);//+
}
...
...
// Whenever the text box got focus, begin listening to window-wide clicks.
// This method shall be bounded in xaml or elsewhere.
// Added method
private void SearchBox_GotFocus(object sender, RoutedEventArgs e) {
AddHandler(Window.PreviewMouseDownEvent, windowWideMouseButtonEventHandler);
}
// The handler method
// Added method
private void OnWindowWideMouseEvent(object sender, MouseButtonEventArgs e) {
// Exclude the text box itself.
if (!FocusManager.GetFocusedElement(this).IsMouseOver) {
// Unregister the already-used handler.
RemoveHandler(Window.PreviewMouseDownEvent, windowWideMouseButtonEventHandler);
// Do something, save text or cancel focus.
}
}
...
}
在XxxWindow.xaml
中为TextBox
设置GotFocus
属性。
<TextBox ... GotFocus="SearchBox_GotFocus">
...
</TextBox>
。
关于这个:添加了previewmousedownoutside ecapturedelement -但不能让它触发。
我只有在调用CaptureMouse
时显示MessageBox时才会触发它,这在现实世界中是不应该发生的。也许这是为弹出窗口设计的