1

フォームに「承認ボタン」(WPFの場合:IsDefault = "True")があると便利です。

Windowsフォームの世界では、ボタンの対応するClickイベントで、UIからオブジェクトにデータを読み取るために使用していました。

ただし、WPFでは、データバインディングを使用する必要があります。Windowのコンストラクターで、this.DataContext=test;を設定します。

そして、ここで問題が発生します。ユーザーがTextBox2にテキストを入力し、Enterキーを押します。これで、[OK]ボタンにバインドされたコマンドが実行され、データが保存されます。

しかし、それは正しいデータではありません!なんで?TextBox2はまだフォーカスを失っていないため、ViewModelはまだ更新されていません。UpdateSourceTriggerをPropertyChangedに変更することは必ずしも適切ではありません(たとえば、フォーマットされた数値)。私は一般的な解決策を探しています。

このような問題をどのように克服しますか?

4

1 に答える 1

0

通常、カスタムの添付プロパティを使用して、Enterキーが押されたときにバインディングソースを更新するようにWPFに指示します

XAMLでは次のように使用されます。

<TextBox Text="{Binding SomeProperty}" 
         local:TextBoxProperties.EnterUpdatesTextSource="True" />

また、添付プロパティのコードは次のとおりです。

public class TextBoxProperties
{
    // When set to True, Enter Key will update Source
    public static readonly DependencyProperty EnterUpdatesTextSourceProperty =
        DependencyProperty.RegisterAttached("EnterUpdatesTextSource", typeof(bool),
                                            typeof(TextBoxProperties),
                                            new PropertyMetadata(false, EnterUpdatesTextSourcePropertyChanged));

    // Get
    public static bool GetEnterUpdatesTextSource(DependencyObject obj)
    {
        return (bool)obj.GetValue(EnterUpdatesTextSourceProperty);
    }

    // Set
    public static void SetEnterUpdatesTextSource(DependencyObject obj, bool value)
    {
        obj.SetValue(EnterUpdatesTextSourceProperty, value);
    }

    // Changed Event - Attach PreviewKeyDown handler
    private static void EnterUpdatesTextSourcePropertyChanged(DependencyObject obj,
                                                              DependencyPropertyChangedEventArgs e)
    {
        var sender = obj as UIElement;
        if (obj != null)
        {
            if ((bool)e.NewValue)
            {
                sender.PreviewKeyDown += OnPreviewKeyDownUpdateSourceIfEnter;
            }
            else
            {
                sender.PreviewKeyDown -= OnPreviewKeyDownUpdateSourceIfEnter;
            }
        }
    }

    // If key being pressed is the Enter key, and EnterUpdatesTextSource is set to true, then update source for Text property
    private static void OnPreviewKeyDownUpdateSourceIfEnter(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.Enter)
        {
            if (GetEnterUpdatesTextSource((DependencyObject)sender))
            {
                var obj = sender as UIElement;
                BindingExpression textBinding = BindingOperations.GetBindingExpression(
                    obj, TextBox.TextProperty);

                if (textBinding != null)
                    textBinding.UpdateSource();
            }
        }
    }
}
于 2012-07-05T13:01:03.297 に答える