0

警告 -- WPF に関しては初心者です。だから私がやろうとしているのは、ViewModel の文字列プロパティにバインドされたテキスト ボックスを持つことです。ユーザーがテキストボックスをクリアすると、ユーザーが最初に持っていたもの(ウィンドウが開いたとき)に自動的に戻ります。基本的に、ユーザーがテキストボックスをクリアできないようにしています。

現在、私の WPF は TwoWay としてバインドされており、UpdateSourceTrigger を PropertyChanged に設定しています。ユーザーが小さな変更を加えたときに ViewModel のプロパティが更新されるのが好きなので、その UpdateSourceTrigger を保持したいと思います。そうすれば、ユーザーが何かをしたときに他の UI を実行できます (たとえば、ユーザーが何かを変更したために [保存] ボタンを更新します)。

現在、ViewModel のプロパティは次のようになっています。元の値を使用しようとしています。

public string SourceName
{
    get { return this.sourceName; }
    set
    {
        if (!this.sourceName.Equals(value, StringComparison.OrdinalIgnoreCase))
        {
            if (!string.IsNullOrWhiteSpace(value))
                this.sourceName = value;
            else
                this.sourceName = this.configuredSource.Name;

            RaisePropertyChanged("SourceName");
        }
    }
}

私が抱えている問題は、私が設定した UpdateSourceTrigger のために、ビューが私の 'RaisePropertyChanged' を無視していると思うことです。トリガーを取り除くと、これは機能しますが、UI を更新するには、コントロールからフォーカスを失う必要があります。したがって、可能であればトリガーを保持したいのです。

ユーザーがテキストボックスをクリアした場合、元の値に戻す良い方法はありますか?

4

2 に答える 2

0

問題はUpdateSourceTrigger、WPF に関する限り、プロパティに渡す値が取得する値であるという事実ほどではありません。再帰的なサイクルを回避するために、発生させたプロパティ変更イベントは無視されます。

次のように、別のメッセージでイベントを発生させる必要があります。

public string SourceName
{
    get { return this.sourceName; }
    set
    {
        if (!this.sourceName.Equals(value, StringComparison.OrdinalIgnoreCase))
        {
            if (!string.IsNullOrWhiteSpace(value))
            {
                this.sourceName = value;
                RaisePropertyChanged("SourceName");
            }
            else
            {
                this.sourceName = this.configuredSource.Name;
                this.dispatcherService.BeginInvoke(() => this.RaisePropertyChanged("SourceName"));
            }
        }
    }
}

DispatcherVM から にアクセスするための標準的な方法がないため (MVVM フレームワークで提供されている場合を除く)、これは一種の疑似コードです。上記のように、私は通常、同期的および非同期的に呼び出すための優れたインターフェイスを備えたサービスにラップします。

とにかく、ポイントは、別のメッセージにあるため、今回は WPF がイベントを取得することです。その結果、UI に変更が反映されます。

于 2012-07-16T19:18:12.343 に答える
0

私はそれを働かせました。解決策は、プロパティを「愚か」にして、空に設定できるようにすることでした。

public string SourceName
{
    get { return this.sourceName; }
    set
    {
        if (!this.sourceName.Equals(value, StringComparison.OrdinalIgnoreCase))
        {
            this.sourceName = value;
            RaisePropertyChanged("SourceName");
        }
    }
}

次に、テキストボックスでフォーカスが失われるたびに発生する RelayCommand (MVVM Light) を用意します。

public RelayCommand SourceNameLostFocusCommand
{
    get 
    { 
        return new RelayCommand(() => 
            {
                if (string.IsNullOrWhiteSpace(this.SourceName))
                    this.SourceName = this.configuredSource.Title;
            }); 
    }
}

これは、フォーカスを失ったときに RelayCommand を起動するための私の xaml のスニペットです。

xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WPF4"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"

<TextBox Text="{Binding Path=SourceName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
   <i:Interaction.Triggers>
      <i:EventTrigger EventName="LostFocus">
         <cmd:EventToCommand Command="{Binding SourceNameLostFocusCommand, Mode=OneWay}" />
      </i:EventTrigger>
   </i:Interaction.Triggers>
</TextBox>
于 2012-07-16T20:31:53.437 に答える