简体   繁体   English

C#WPF MVVM Light无法执行

[英]C# WPF MVVM Light CanExecute not recognized

i am learning WPF and MVVM at the moment and having a little problem. 我目前正在学习WPF和MVVM,并且有一些问题。

Im using MVVM Light and i want some Buttons to be dis/enabled after a validation, but its not using the functions. 我正在使用MVVM Light,我希望在验证后禁用/启用某些按钮,但不使用功能。

ViewModelMain: ViewModelMain:

using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.Entity;

namespace EF_MVVM_Test
{
    public class ViewModelMain : ViewModelBase
    {
        public RelayCommand AddAuthorCommand { get; private set; }
        public RelayCommand DeleteAuthorCommand { get; private set; }
        public RelayCommand RefreshCommand { get; private set; }
        public RelayCommand SaveCommand { get; private set; }

        public ObservableCollection<Author> Authors { get; set; }
        private LibraryContext db;

        private Author _SelectedAuthor;
        public Author SelectedAuthor
        {
            get { return _SelectedAuthor; }
            set { Set("SelectedAuthor", ref _SelectedAuthor, value); }
        }

        private Author _NewAuthor;
        public Author NewAuthor
        {
            get { return _NewAuthor; }
            set { Set("NewAuthor", ref _NewAuthor, value); }
        }

        public ViewModelMain()
        {
            db = new LibraryContext();
            db.Author.Load();
            Authors = db.Author.Local;

            AddAuthorCommand = new RelayCommand(ExecuteAddAuthorCommand, CanExecuteAddAuthorCommand);
            DeleteAuthorCommand = new RelayCommand(ExecuteDeleteAuthorCommand, CanExecuteDeleteAuthorCommand);
            RefreshCommand = new RelayCommand(ExecuteRefreshListCommand);
            SaveCommand = new RelayCommand(ExecuteSaveCommand);

            NewAuthor = new Author();
        }

        private void ExecuteAddAuthorCommand()
        {
            db.Author.Add(_NewAuthor);
            NewAuthor = new Author();
        }
        private void ExecuteDeleteAuthorCommand()
        {
            db.Author.Remove(SelectedAuthor);
        }
        private void ExecuteRefreshListCommand()
        {
            db.Author.Load();
            Authors = db.Author.Local;
        }
        private void ExecuteSaveCommand()
        {
            db.SaveChanges();
        }

        private bool CanExecuteAddAuthorCommand()
        {
            return (!string.IsNullOrEmpty(NewAuthor.Name) && NewAuthor.Birthday != null);
        }
        private bool CanExecuteDeleteAuthorCommand()
        {
            return SelectedAuthor != null;
        }
    }
}

XAML: XAML:

<StackPanel>
        <DataGrid ItemsSource="{Binding Authors}" SelectedItem="{Binding SelectedAuthor}" AutoGenerateColumns="False" Height="200" Margin="5" CanUserAddRows="False" CanUserDeleteRows="False">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
                <DataGridTextColumn Header="Birthday" Binding="{Binding Birthday}"/>
            </DataGrid.Columns>
        </DataGrid>
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="Name" Margin="5" VerticalAlignment="Center"/>
            <TextBox Height="25" Width="70" Margin="5" Text="{Binding NewAuthor.Name}"/>
            <TextBlock Text="Geburtstag" Margin="5" VerticalAlignment="Center"/>
            <DatePicker Height="25" Width="130" Margin="5" SelectedDate="{Binding NewAuthor.Birthday}"/>
            <Button Margin="5" Height="25" Width="80" Content="Hinzufügen" HorizontalAlignment="Left" Command="{Binding AddAuthorCommand}"/>
            <Button Margin="5" Height="25" Width="80" Content="Löschen" HorizontalAlignment="Left" Command="{Binding DeleteAuthorCommand}"/>
        </StackPanel>
        <StackPanel Orientation="Horizontal">
            <Button Width="120" Height="25" Content="Speichern" HorizontalAlignment="Left" Margin="5" Command="{Binding SaveCommand}"/>
            <!--Button Width="120" Height="25" Content="Aktualisieren" HorizontalAlignment="Left" Margin="5" Command="{Binding RefreshCommand}"/-->
        </StackPanel>
</StackPanel>

any ideas why the buttons aren't using the canexecute functions? 有什么想法为什么按钮不使用canexecute函数?

Your problem is the namespace you're using: 您的问题是您使用的名称空间:

using GalaSoft.MvvmLight.Command;

Replace it with: 替换为:

using GalaSoft.MvvmLight.CommandWpf;

WPF's CommandManager calls CanExecute when it detects a UI changes? WPF的CommandManager在检测到UI更改时调用CanExecute What constitutes a UI change? 什么是UI更改? Adding and removing elements, some binding updates, visual state changes. 添加和删​​除元素, 一些绑定更新,视觉状态更改。 Basically, whenever WPF feels like it. 基本上,只要WPF有这种感觉。 It is unreliable. 这是不可靠的。

How can you skirt this? 你怎么能穿裙子? When you need to refresh a RelayCommand , call RelayCommand.RaiseCanExecuteChanged() . 当您需要刷新RelayCommand ,请调用RelayCommand.RaiseCanExecuteChanged() This method raises an event that notifies WPF that it should re-evaluate the status of the command. 此方法引发一个事件,通知WPF它应重新评估命令的状态。

Looks like you have the same problem as me a few days ago. 看来您几天前和我有同样的问题。

ICommand doesn't work ICommand不起作用

ICommand.CanExecute is not calling, because of course you don't say the button: "The ability of the button click may change when I insert something in the TextBox ". ICommand.CanExecute没有调用,因为您当然不会说按钮:“当我在TextBox插入内容时,按钮单击的能力可能会改变”。 So your button doesn't realize that he can be enable if textbox text changes. 因此,如果文本框文本发生更改,您的按钮不会意识到可以启用他。 You must tell the button explicitly that it should check ICommand.CanExecute when the text changes, by raising the ICommand.CanExecuteChanged event when textbox tex has changed. 您必须明确告诉按钮,当文本更改时,应该通过在文本框tex更改时引发ICommand.CanExecuteChanged事件来检查ICommand.CanExecute

我认为,不幸的是,您必须在分配SelectedAuthor并拦截NewAuthor对象的属性更改后,调用RelayCommand对象的RaiseCanExecuteChanged方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM