更改MVVM-WPF中文本块的背景颜色(并保留)

时间:2012-08-17 19:39:57

标签: wpf mvvm

以下是我的工作代码:当我单击按钮(但是微秒)时,文本和背景颜色属性会发生变化,然后再设置回默认文本/颜色。好像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;
    }
}

2 个答案:

答案 0 :(得分:2)

只要绑定发生变化,就会调用CanExecute方法。因此,更改Execute方法(颜色)中的绑定将导致再次调用CanExecute。

相反,为什么不在构造函数中初始化颜色私有成员一次,如下所示。

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

注意,text属性也是如此。通常,所有属性私有成员都应该在initialize(构造函数)上设置默认值,因为这样可以避免对INotifyPropertyChanged进行不必要的调用。

此外,为了测试代码的行为方式并确认这一点,只需在CanExecute方法中设置一些断点,以查看程序流的行为方式。

答案 1 :(得分:1)

您的问题是您不应该在myCanOkExecute中对您的属性进行任何设置...因为正在调用它并将您的属性更改回黄色等。

命令的CanExecute方法可以被多次调用,有时当你不期望...时。当焦点变为另一个控件时,某些控件正在编辑/发送时按下,执行一个Command后,当有人调用CommandManager.InvalidateRequerySuggested等时

因此,您点击并执行按钮后不久就会调用myCanOkExecute。