3

では、MVVM パターンを使用してボタン クリックで TextBox にフォーカスする方法は?

この回答に基づいて、最初のクリックで機能する簡単なテストプロジェクトを作成しましたが、その後はフォーカスが設定されなくなりました。何が恋しいですか?

XAML (ビュー)

<Grid>
    <TextBox Height='23' HorizontalAlignment='Left' Margin='12,12,0,0' VerticalAlignment='Top' Width='120'
             Text='{Binding TheText}'
             local:FocusExtension.IsFocused="{Binding IsFocused}"/>
    <Button Content='Click' Height='23' HorizontalAlignment='Left' Margin='138,11,0,0' VerticalAlignment='Top' Width='75' 
            Command='{Binding ClickCommand}'/>
    <Button Content='Just to deFocus' Height='28' HorizontalAlignment='Left' Margin='14,44,0,0' Name='button1' VerticalAlignment='Top' Width='199' />
</Grid>

ビューモデル

public class ViewModel : INotifyPropertyChanged
{
    public string TheText { get; set; }
    public bool IsFocused { get; set; }

    private RelayCommand _clickCommand;
    public ICommand ClickCommand
    {
        get { return _clickCommand ?? (_clickCommand = new RelayCommand(param => this.OnClick())); }
    }
    private void OnClick()
    {
        IsFocused = true;
        RaisePropertyChanged("IsFocused");
    }

    #region INotifyPropertyChanged

    public event PropertyChangedEventHandler PropertyChanged;

    public void RaisePropertyChanged(string propName)
    {
        if (this.PropertyChanged != null)
            this.PropertyChanged(this, new PropertyChangedEventArgs(propName));
    }

    #endregion
}

そして、怠惰な人のためのすぐに使えるプロジェクト(VS2010)のダウンロードリンクがあります;)

4

3 に答える 3

7

初期のデフォルトが上書きされた後、添付プロパティの値が false に戻ることはありません。したがって、VM を trueに設定するときに を起動する必要がFocusExtensionないため、クラスは を呼び出しFocus()TextBoxいません。PropertyChangedIsFocused

を切り替えるOnIsFocusedPropertyChanged(...)

から:

private static void OnIsFocusedPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    var uie = (UIElement)d;
    if ((bool)e.NewValue)
        uie.Focus(); // Don't care about false values.
}

private static void OnIsFocusedPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
  var uie = (UIElement)d;
  if (!((bool)e.NewValue))
    return;
  uie.Focus();
  uie.LostFocus += UieOnLostFocus;
}

private static void UieOnLostFocus(object sender, RoutedEventArgs routedEventArgs) {
  var uie = sender as UIElement;
  if (uie == null)
    return;
  uie.LostFocus -= UieOnLostFocus;
  uie.SetValue(IsFocusedProperty, false);
}

アップデート:

上記の変更に加えて、次のことも確認してください。

local:FocusExtension.IsFocused="{Binding IsFocused}"

に切り替えられます

local:FocusExtension.IsFocused="{Binding IsFocused, Mode=TwoWay}"

作業中のダウンロード リンク

別のアップデート

クラススイッチMode=TwoWayでこの添付プロパティのデフォルトとして設定するにはFocusExtension

public static readonly DependencyProperty IsFocusedProperty = DependencyProperty.RegisterAttached(
  "IsFocused",
  typeof(bool),
  typeof(FocusExtension),
  new UIPropertyMetadata(
    false,
    OnIsFocusedPropertyChanged));

public static readonly DependencyProperty IsFocusedProperty = DependencyProperty.RegisterAttached(
  "IsFocused",
  typeof(bool),
  typeof(FocusExtension),
  new FrameworkPropertyMetadata(
    false,
    FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
    OnIsFocusedPropertyChanged));

Mode=TwoWay上記の宣言で xaml での明示的な指定をスキップできます。

于 2013-06-06T15:23:31.737 に答える
1

lostFocus イベントのコマンドを作成し、フォーカスが失われたときに isFocused プロパティを false に設定すると、機能します。次のようなものを書くことができるよりも、Interactivity および Interactions ライブラリをプロジェクトに追加します。

 <i:Interaction.Triggers>
    <i:EventTrigger EventName="LostFocus">
        <ei:CallMethodAction TargetObject="{Binding}" MethodName="OnLostFocus"/>
    </i:EventTrigger>
 </i:Interaction.Triggers>

そしてあなたのviewModelに次のように書いてください:

public void OnLostFocus()
{IsFocused = false;}

RaisePropertyChanged をプロパティのセッターに移動します

于 2013-06-06T15:01:20.813 に答える
1

私は以前に同じ問題を抱えていました。私はトリックをしました。OnClick メソッドで、次のようにします。

if(IsFocus == true)
   IsFocus = false;
IsFocus = true;
于 2013-06-07T07:47:55.313 に答える