WPF-MVVM 中的错误处理/禁用按钮

发布于 2024-10-07 07:42:39 字数 3162 浏览 0 评论 0原文

我在查看错误处理时遇到问题。我使用 caliburn.micro 和 MEF。

我的虚拟机看起来像这样:

[Export(typeof(IShellViewModel))]
public class ShellViewModel : PropertyChangedBase, IShellViewModel,IDataErrorInfo
{

    #region Private members

    private User _user;
    private Dictionary<string, bool> _validProperties;
    private bool _allPropertiesValid;

    #endregion

    #region Private methods

    private void ValidateProperties()
    {
        if (_validProperties.Values.Any(isValid => !isValid))
        {
            AllPropertiesValid = false;
            return;
        }
        AllPropertiesValid = true;
    }
    #endregion

    #region Constructor

    public ShellViewModel()
    {
        _user = new User();
        _validProperties = new Dictionary<string, bool> {{"Nick", false}, {"Password", false}};
    }

    #endregion

    #region Properties

    public bool AllPropertiesValid
    {
        get { return _allPropertiesValid; }
        set
        {
            if (_allPropertiesValid != value)
            {
                _allPropertiesValid = value;
                NotifyOfPropertyChange("AllPropertiesValid");
            }
        }
    }

    #endregion

    #region Implementation of IShellViewModel

    public string Nick
    {
        get { return _user.Nick; }
        set
        {
            _user.Nick = value;
            NotifyOfPropertyChange("Nick");
        }
    }

    public string Password
    {
        get { return _user.Password; }
        set
        {
            _user.Password = value;
            NotifyOfPropertyChange("Password");
        }
    }

    public void EmptyLogOn()
    { 
        MessageBox.Show(string.Format("LogOn on server with credential: {0}, {1}", Nick, Password));
    }

    public void LogOn(string nick, string password)
    {

        MessageBox.Show(string.Format("LogOn on server with credential: {0}, {1}", nick, password));
    }

    #endregion

    #region Implementation of IDataErrorInfo

    public string Error
    {
        get { return (_user as IDataErrorInfo).Error; }
    }

    public string this[string propertyName]
    {
        get
        {
            string error = (_user as IDataErrorInfo)[propertyName];
            _validProperties[propertyName] = String.IsNullOrEmpty(error) ? true : false;
            ValidateProperties();
            CommandManager.InvalidateRequerySuggested();
            return error;
        }
    }

    #endregion
}

如果我有一些错误,我将属性 AllPropertiesValid 设置为 false。我将此属性绑定到 Button 属性 IsEnabled 上。

所以在视图中我有这个:

<Button IsEnabled="{Binding AllPropertiesValid, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
        Micro:Message.Attach="EmptyLogOn"
        Content="Prihlás ma"
        Width="100" 
        Height="25" 
        VerticalAlignment="Center"
        Grid.Row="2"
        Grid.ColumnSpan="2"></Button>
<Label Content="{Binding AllPropertiesValid}" Grid.Row="3"/>

但如果属性 AllPropertiesValid 为 false 按钮​​仍处于启用状态。我检查 AllPropertiesValid 的值(我将此属性绑定到标签上并且标签内容为 false)为 false。

怎么了 ?感谢您的提前。

编辑:在设计器中按钮被禁用,但加载窗口按钮时启用。

I have problem with error handling in view. I use caliburn.micro and MEF.

My VM look like this:

[Export(typeof(IShellViewModel))]
public class ShellViewModel : PropertyChangedBase, IShellViewModel,IDataErrorInfo
{

    #region Private members

    private User _user;
    private Dictionary<string, bool> _validProperties;
    private bool _allPropertiesValid;

    #endregion

    #region Private methods

    private void ValidateProperties()
    {
        if (_validProperties.Values.Any(isValid => !isValid))
        {
            AllPropertiesValid = false;
            return;
        }
        AllPropertiesValid = true;
    }
    #endregion

    #region Constructor

    public ShellViewModel()
    {
        _user = new User();
        _validProperties = new Dictionary<string, bool> {{"Nick", false}, {"Password", false}};
    }

    #endregion

    #region Properties

    public bool AllPropertiesValid
    {
        get { return _allPropertiesValid; }
        set
        {
            if (_allPropertiesValid != value)
            {
                _allPropertiesValid = value;
                NotifyOfPropertyChange("AllPropertiesValid");
            }
        }
    }

    #endregion

    #region Implementation of IShellViewModel

    public string Nick
    {
        get { return _user.Nick; }
        set
        {
            _user.Nick = value;
            NotifyOfPropertyChange("Nick");
        }
    }

    public string Password
    {
        get { return _user.Password; }
        set
        {
            _user.Password = value;
            NotifyOfPropertyChange("Password");
        }
    }

    public void EmptyLogOn()
    { 
        MessageBox.Show(string.Format("LogOn on server with credential: {0}, {1}", Nick, Password));
    }

    public void LogOn(string nick, string password)
    {

        MessageBox.Show(string.Format("LogOn on server with credential: {0}, {1}", nick, password));
    }

    #endregion

    #region Implementation of IDataErrorInfo

    public string Error
    {
        get { return (_user as IDataErrorInfo).Error; }
    }

    public string this[string propertyName]
    {
        get
        {
            string error = (_user as IDataErrorInfo)[propertyName];
            _validProperties[propertyName] = String.IsNullOrEmpty(error) ? true : false;
            ValidateProperties();
            CommandManager.InvalidateRequerySuggested();
            return error;
        }
    }

    #endregion
}

If I have som error I set properties AllPropertiesValid on false. I bind this properties on Button properties IsEnabled.

So in View I have this:

<Button IsEnabled="{Binding AllPropertiesValid, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
        Micro:Message.Attach="EmptyLogOn"
        Content="Prihlás ma"
        Width="100" 
        Height="25" 
        VerticalAlignment="Center"
        Grid.Row="2"
        Grid.ColumnSpan="2"></Button>
<Label Content="{Binding AllPropertiesValid}" Grid.Row="3"/>

But if properties AllPropertiesValid is false Button is still enabled. I check the value of AllPropertiesValid (I bind this properties on label and label content is false) is false.

What’s wrong ? Thank for advance.

EDIT: In designer is button disabled, but when is loaded window button is enable.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

锦爱 2024-10-14 07:42:39

如果您正在使用MVVM,那么您应该使用ICommand(或其他更高级别的变体,例如CommandBase,...),因为您需要单击按钮时执行某些操作。

在本例中,您绑定到 ViewModel 上的命令属性,在命令中的 CanExecute 上返回 false,并且按钮被禁用。有时您必须调用CommandManager.InvalidateRequerySuggested()

这并不能解释为什么您的代码不起作用。老实说,我觉得还不错。

If you are doing MVVM then you should be using ICommand (or other higher-level variants such as CommandBase, ...) since you need to do something when button is clicked.

In this case you bind to a command property on the ViewModel, you return false on the CanExecute in the command and button is disabled. Sometimes you have to call CommandManager.InvalidateRequerySuggested().

This does not explain why your code is not working. To be honest, it looks alright to me.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文