117

デフォルトのデータバインディングはオンTextBoxであり、フォーカスを失ったTwoWay場合にのみテキストをプロパティにコミットします。TextBox

Enter? のキーを押したときにデータバインディングを行う簡単な XAML の方法はありTextBoxますか。コードビハインドで行うのは非常に簡単ですが、これTextBoxが複雑なDataTemplate.

4

12 に答える 12

62

これが私がこの問題を解決した方法です。コード ビハインドに入る特別なイベント ハンドラーを作成しました。

private void TextBox_KeyEnterUpdate(object sender, KeyEventArgs e)
{
    if (e.Key == Key.Enter)
    {
        TextBox tBox = (TextBox)sender;
        DependencyProperty prop = TextBox.TextProperty;

        BindingExpression binding = BindingOperations.GetBindingExpression(tBox, prop);
        if (binding != null) { binding.UpdateSource(); }
    }
}

次に、これを XAML の KeyUp イベント ハンドラーとして追加しました。

<TextBox Text="{Binding TextValue1}" KeyUp="TextBox_KeyEnterUpdate" />
<TextBox Text="{Binding TextValue2}" KeyUp="TextBox_KeyEnterUpdate" />

イベント ハンドラーは、そのsender参照を使用して、独自のバインディングを更新します。イベント ハンドラーは自己完結型であるため、複雑な DataTemplate で機能する必要があります。この 1 つのイベント ハンドラーを、この機能を必要とするすべてのテキスト ボックスに追加できるようになりました。

于 2012-11-08T12:26:37.530 に答える
47

あなたが説明していることを行うための「純粋なXAML」の方法があるとは思いません。次のようにUpdateSourceTriggerプロパティを設定することで、TextBox 内のテキストが変更されるたびに (TextBox がフォーカスを失ったときではなく) 更新されるようにバインディングを設定できます。

<TextBox Name="itemNameTextBox"
    Text="{Binding Path=ItemName, UpdateSourceTrigger=PropertyChanged}" />

UpdateSourceTrigger を "Explicit" に設定し、TextBox の PreviewKeyDown イベントを処理して (Enter キーを探して)、目的を達成できますが、コード ビハインドが必要になります。おそらく、ある種の添付プロパティ (私のEnterKeyTraversalプロパティに似ています) が機能するでしょう。

于 2009-02-18T22:55:20.670 に答える
25

TextBox から継承する独自のコントロールを簡単に作成し、プロジェクト全体で再利用できます。

これに似たものが機能するはずです:

public class SubmitTextBox : TextBox
{
    public SubmitTextBox()
        : base()
    {
        PreviewKeyDown += new KeyEventHandler(SubmitTextBox_PreviewKeyDown);
    }

    void SubmitTextBox_PreviewKeyDown(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.Enter)
        {
            BindingExpression be = GetBindingExpression(TextBox.TextProperty);
            if (be != null)
            {
                be.UpdateSource();
            }
        }
    }
}

このステップを回避する方法があるかもしれませんが、それ以外の場合は、次のようにバインドする必要があります (Explicit を使用):

<custom:SubmitTextBox
    Text="{Binding Path=BoundProperty, UpdateSourceTrigger=Explicit}" />
于 2009-06-10T19:58:08.950 に答える
16

Ben と ausadmin の両方のソリューションを組み合わせると、非常に MVVM に適したソリューションになります。

<TextBox Text="{Binding Txt1, Mode=TwoWay, UpdateSourceTrigger=Explicit}">
    <TextBox.InputBindings>
        <KeyBinding Gesture="Enter" 
                    Command="{Binding UpdateTextBoxBindingOnEnterCommand}"
                    CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type TextBox}}}" />
    </TextBox.InputBindings>
</TextBox>

...これは、TextBoxそれ自体をパラメーターとしてに渡すことを意味しますCommand

これにより、次のようになります( VM で スタイルの実装Commandを使用している場合)。DelegateCommand

    public bool CanExecuteUpdateTextBoxBindingOnEnterCommand(object parameter)
    {
        return true;
    }

    public void ExecuteUpdateTextBoxBindingOnEnterCommand(object parameter)
    {
        TextBox tBox = parameter as TextBox;
        if (tBox != null)
        {
            DependencyProperty prop = TextBox.TextProperty;
            BindingExpression binding = BindingOperations.GetBindingExpression(tBox, prop);
            if (binding != null) 
                binding.UpdateSource();
        }
    }

このCommand実装は、コード ビハインドのすべてのコードに使用できますが、これを独自のクラスに配置して、VM にTextBox依存しないようにすることもできます。System.Windows.Controlsそれは、コード ガイドラインがどれほど厳格であるかによって異なります。

于 2014-11-06T10:57:51.733 に答える
4

これは、私には非常に簡単で、AttachedBehaviour を追加するよりも簡単に思えるアプローチです (これも有効なソリューションです)。デフォルトの UpdateSourceTrigger (TextBox の LostFocus) を使用し、コマンドにバインドされた Enter キーに InputBinding を追加します。

xamlは次のとおりです

       <TextBox Grid.Row="0" Text="{Binding Txt1}" Height="30" Width="150">
        <TextBox.InputBindings>
            <KeyBinding Gesture="Enter" 
                        Command="{Binding UpdateText1Command}"
                        CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type TextBox}},Path=Text}" />
        </TextBox.InputBindings>
    </TextBox>

次に、コマンド メソッドは次のとおりです。

Private Function CanExecuteUpdateText1(ByVal param As Object) As Boolean
    Return True
End Function
Private Sub ExecuteUpdateText1(ByVal param As Object)

    If TypeOf param Is String Then
        Txt1 = CType(param, String)
    End If
End Sub

TextBox はプロパティにバインドされています

 Public Property Txt1 As String
    Get
        Return _txt1
    End Get
    Set(value As String)
        _txt1 = value
        OnPropertyChanged("Txt1")
    End Set
End Property

これまでのところ、これはうまく機能しているようで、TextBox で Enter Key イベントをキャッチします。

于 2012-11-15T04:09:57.803 に答える
2

TextBox で MultiBinding を使用している場合は、BindingOperations.GetMultiBindingExpressionの代わりにメソッドを使用する必要がありますBindingOperations.GetBindingExpression

// Get the correct binding expression based on type of binding
//(simple binding or multi binding.
BindingExpressionBase binding = 
  BindingOperations.GetBindingExpression(element, prop);
if (binding == null)
{
    binding = BindingOperations.GetMultiBindingExpression(element, prop);
}

if (binding != null)
{
     object value = element.GetValue(prop);
     if (string.IsNullOrEmpty(value.ToString()) == true)
     {
         binding.UpdateTarget();
     }
     else
     {
          binding.UpdateSource();
     }
}
于 2011-09-28T16:11:56.193 に答える
1

ここでは、添付されたビヘイビアを使用して非常にエレガントに回答しました。

Enterキーを押した後にテキストボックスにフォーカスを失うWPFの方法

于 2016-08-30T18:38:17.270 に答える
0

別の解決策(xamlを使用していませんが、それでもかなりきれいだと思います)。

class ReturnKeyTextBox : TextBox
{
    protected override void OnKeyUp(KeyEventArgs e)
    {
        base.OnKeyUp(e);
        if (e.Key == Key.Return)
            GetBindingExpression(TextProperty).UpdateSource();
    }
}
于 2020-04-28T06:22:28.577 に答える