1

私が持っている作業コードは次のとおりです。ボタンをクリックすると(ただしマイクロ秒の間)、テキストと背景色のプロパティが変更され、デフォルトのテキスト/色に戻ります。RaisePropertyChangedが何度もトリガーされているようです。誰かが私が間違っていることを指摘するのを手伝ってもらえますか?

MainWindow.xamlコード

 <Window x:Class="BuiltIn_Custom_Commands_Eg.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <StackPanel HorizontalAlignment="Center">
        <TextBlock Text="{Binding txtblck_text, StringFormat=Default: {0}}" Padding="10" FontStyle="Italic" Background="{Binding txtblck_color}"/>
        <Button Content="Change Color" Width="100" Height="30" Margin="20" Command="{Binding OkCommand}" />
    </StackPanel>
</Grid>

ViewModelコード:

class Example_ViewModel : ViewModelBase
{
    #region Properties
    private string _txtblck_text;
    private Brush _txtblck_color;
    public ICommand OkCommand {get; set;}

    public string txtblck_text
    {
        get { return _txtblck_text; }
        set 
        { 
            _txtblck_text = value;
            RaisePropertyChanged("txtblck_text");
        }
    }

    public Brush txtblck_color
    {
        get { return _txtblck_color; }
        set
        {
            _txtblck_color = value;
            RaisePropertyChanged("txtblck_color");
        }
    }
    #endregion

    #region Constructor
    public Example_ViewModel()
    {
        OkCommand = new myCommand(myOkExecute, myCanOkExecute);
    }
    #endregion

    private void myOkExecute(object parameter)
    {
        txtblck_color = Brushes.CadetBlue;
        //RaisePropertyChanged("txtblck_color");

        txtblck_text = "You Clicked me!!!";
        //RaisePropertyChanged("txtblck_text");
    }

    private bool myCanOkExecute(object parameter)
    {
        txtblck_color = Brushes.Yellow;
        txtblck_text = "You havent clicked me!!!";
        return true;
    }
}
4

2 に答える 2

2

CanExecuteメソッドは、バインディングが変更されるたびに呼び出され、呼び出される必要があります。したがって、Executeメソッド(色)のバインディングを変更すると、CanExecuteが再度呼び出されます。

代わりに、次のようにコンストラクターで一度colorsプライベートメンバーを初期化しないのはなぜですか。

public Example_ViewModel()
{
    OkCommand = new myCommand(myOkExecute, myCanOkExecute);
    _txtblck_color =  = Brushes.Yellow;
}

同じことがtextプロパティにも当てはまることに注意してください。通常、すべてのプロパティプライベートメンバーは、初期化(コンストラクター)のデフォルトで設定する必要があります。これにより、INotifyPropertyChangedへの不要な呼び出しが回避されます。

また、コードがどのように動作しているかをテストし、これを確認するには、CanExecuteメソッドにいくつかのブレークポイントを設定して、プログラムフローがどのように動作しているかを確認します。

于 2012-08-17T20:02:26.663 に答える
1

あなたの問題は、myCanOkExecuteでプロパティの設定を行うべきではないということです...それは呼び出されてプロパティを黄色に戻すなどの理由でです。

コマンドのCanExecuteメソッドは複数回呼び出される可能性があり、予期しない場合もあります...たとえば、フォーカスが別のコントロールに変わったとき、特定のコントロールが編集/キー押下されたとき、コマンドが実行された後、誰かがCommandManager.InvalidateRequerySuggestedなどを呼び出します。

したがって、ボタンをクリックして実行した直後にmyCanOkExecuteが呼び出されます。

于 2012-08-17T21:04:40.440 に答える