如何在MVVMLight RelayCommand场景中更新UI?

时间:2013-09-28 06:01:47

标签: c# windows-phone-7 mvvm windows-phone-8 mvvm-light

这是一个简单的屏幕,其中一个textblock最初是“”,button称为“设置文字”,将文字设置为textblockanother button “明文”始终清除textblock中的文字。这就是XAML的样子。

<StackPanel>
    <TextBlock Text="{Binding DisplayText, Mode=TwoWay}"></TextBlock>
    <Button Content="Set Text" Command="{Binding SetTextCommand}"></Button>
    <Button Content="Clear Text" Command="{Binding CancelCommand}" 
                                 IsEnabled="{Binding CanCancel, Mode=TwoWay}"/>
</StackPanel>

这是我的ViewModel代码。

public class Page1VM : ViewModelBase
    {

        public RelayCommand SetTextCommand { get; private set; }
        public RelayCommand CancelCommand { get; private set; }

        public Page1VM()
        {
            SetTextCommand = new RelayCommand(HandleSetText, CanExecute);
            CancelCommand = new RelayCommand(HandleClearButtonClick, CanExecuteCancel);
        }

        private void HandleSetText(string number)
        {
            DisplayText = number;
        }

        private string _displayText="";
        public string DisplayText
        {
            get { return _displayText; }
            set
            {
                _displayText = value;
                RaisePropertyChanged("DisplayText");
                RaisePropertyChanged("CanCancel");
            }
        }

        private bool _canCancel;
        public bool CanCancel
        {
            get
            {
                if (DisplayText == "")
                {
                    return false;
                }
                else
                {
                    return true;
                }
            }
            set
            {
                _canCancel = value;
                RaisePropertyChanged("CanCancel");
            }
        }

        private bool CanExecute()
        {
            return true;
        }
        private bool CanExecuteCancel()
        {
            if (DisplayText == "")
            {
                return false;
            }
            else
            {
                return true;
            }
        }
        private void HandleClearButtonClick()
        {
            DisplayText = "";
        }
        private void HandleSetText()
        {
            DisplayText = "Hello";
        }
    }

问题:当页面加载时,“清除文本”按钮被禁用,这是预期的,并且可以正常工作。

当我点击“设置文字”时,我通过将文本值设置为名为DisplayText的属性并将RaisePropertyChanged("CanCancel");调用为{{1}}来将文本设置为文本块,但在此之后我的“明文”按钮未启用。它背后的原因是什么?我的文本块显示文本值,但仍未启用“明文”按钮。

1 个答案:

答案 0 :(得分:1)

据我所知,你的例子中有一点混乱:你基本上不使用'RelayCommand'的内置'CanExecute'机制,但是在定义{{{ 1}}'RealyCommand'的方法。 'CanExecute'的想法是自动取消其命令无法执行的控件,因此您不需要手动执行。在'CanExecute'方法中返回'true'并没有多大意义,因为你不一定需要在你的RelayCommand中有一个CanExecute委托(CanExecute就可以了)。您的方案不起作用,因为您没有在'CancelCommand'上调用'RaisCanExecuteChanged()'。

尝试以下实现,我删除了冗余并插入了缺少的'RaiseCanExecuteChanged()'。请参阅注释以获得解释:

... = new RelayCommand(ExecuteCommand);

使用这个简化的ViewModel:     

<StackPanel>
    <TextBlock Text="{Binding DisplayText, Mode=TwoWay}"></TextBlock>
    <Button Content="Set Text" Command="{Binding SetTextCommand}"></Button>
    <Button Content="Clear Text" Command="{Binding CancelCommand}" />
</StackPanel>