簡體   English   中英

單擊文本框時如何更新文本框的綁定

[英]How to update binding of Textbox when clicking off the textbox

在我的應用程序中,我有一個Usercontrol,它代表一個對象的一些配置。 在其中是一個Texblock,其中包含所述對象的名稱。 我希望能夠單擊此文本塊並將其轉換為文本框,以便能夠編輯名稱。

我希望它具有以下3個行為

  1. 按下Enter鍵時,在ViewModel中設置值
  2. 變得可見時獲得鍵盤焦點
  3. 在文本框外單擊鼠標時(如組合框一樣)在ViewModel中設置值

而我目前仍停留在3上。 我該如何使我的文本框滿足要求3-單擊該文本框會設置該值,我已經實現了一些附件行為以使其他2個起作用,但無法使鼠標一個起作用。

我嘗試了以下

  1. 添加了PreviewMouseDown事件-僅在文本框中按下鼠標時似乎被檢測到
  2. 即使在用戶控件中也添加了PreviewMouseDown-即使單擊文本框也似乎被擊中。 另外,它也不是我窗口中唯一的用戶控件,因此無法在更大范圍內使用。
  3. 添加了PreviewMouseDownOutsideCapturedElement-但永遠無法觸發它。
  4. 不再關注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帖子,它們似乎都無法幫助我,他們都建議將其添加到我不能做的window / usercontrol中。

我設法找到了解決方案。

基本上,我在代碼中為文本框的OnGotFocus綁定了一個事件。 當點擊此方法時,它將MouseDown和MouseLeave事件添加到用戶控件。 因此,當您單擊用戶控件中的任何位置時,它都會更新文本框的內容。

如果您離開用戶控件的界限,那么您希望將鼠標向下移動到窗口本身。 同樣,當您移回用戶控件時,要刪除窗口上的鼠標按下事件,或者在離開后在文本框中單擊鼠標時,它將設置該值。

我在這里添加了我的代碼,希望對任何可能遇到類似問題的人來說都是清楚的。

我確信一定有比使用背后的代碼更好的方法,但是我認為我在這里沒有違反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 WindowPage

// 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.xamlTextBox設置GotFocus屬性。

<TextBox ... GotFocus="SearchBox_GotFocus">
...
</TextBox>

做完了

對這個:

添加了PreviewMouseDownOutsideCapturedElement-但永遠無法觸發它。

每當CaptureMouse時顯示一個MessageBox時,我就被激發了,這在現實世界中是不應該發生的。 也許這是為彈出窗口設計的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM