c# - UWP 的 MVVM 模式教程,但它不会绑定(bind)命令,为什么?

标签 c# xaml mvvm uwp uwp-xaml

好的。我正在按照教程掌握我的应用程序的 MVVM 模式。

我已经很好地遵循了教程,我学习了命令部分,当我尝试将命令应用于按钮时它似乎根本不起作用,我的按钮从未禁用。 我看过其他 MVVM 源代码,我的代码似乎还不错,除了我在互联网上发现本教程适用于 WPF,但它也适用于 UWP Windows 10 应用程序。

所以我将粘贴我的类和 Xaml View 。

这是我的模型:

using System.ComponentModel;

namespace MVVMDemo.Model
{
public class Student : INotifyPropertyChanged
{
    private string firstName;
    private string lastName;

    public string FirstName
    {
        get
        {
            return firstName;
        }

        set
        {
            if (firstName != value)
            {
                firstName = value;
                RaisePropertyChanged("FirstName");
                RaisePropertyChanged("FullName");
            }
        }
    }

    public string LastName
    {
        get { return lastName; }

        set
        {
            if (lastName != value)
            {
                lastName = value;
                RaisePropertyChanged("LastName");
                RaisePropertyChanged("FullName");
            }
        }
    }

    public string FullName
    {
        get
        {
            return firstName + " " + lastName;
        }
    }

    public event PropertyChangedEventHandler PropertyChanged = delegate { };

    private void RaisePropertyChanged(string property)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
    }
}
}

我相信模型代码没有错误。 这是我的 View 模型:

using MVVMDemo.Model;
using System.Collections.ObjectModel;

namespace MVVMDemo.ViewModel
{
public class StudentViewModel
{
    /*Let’s add a property of MyICommand type in StudentView Model class. 
     * Now we need to construct an instance in the StudentViewModel. We will
     * use the overloaded constructor of MyICommand that takes two parameters.*/
    public MyICommand DeleteCommand { get; set; }

    /*Now add the implementation of OnDelete and CanDelete methods.*/
    public StudentViewModel()
    {
        LoadStudents();
        DeleteCommand = new MyICommand(OnDelete, CanDelete);
    }

    private bool CanDelete()
    {
        //if (SelectedStudent != null)
        //    return true;
        //return false;
        return SelectedStudent != null;
    }

    private void OnDelete()
    {
        Students.Remove(SelectedStudent);
    }

    /*We also need to add a new SelectedStudent so that the user 
     * can delete the Selected Item from ListBox.*/
    private Student _selectedStudent;

    public Student SelectedStudent
    {
        get
        {
            return _selectedStudent;
        }
        set
        {
            _selectedStudent = value;
            DeleteCommand.RaiseCanExecuteChanged();
        }
    }
    public ObservableCollection<Student> Students
    {
        get;
        set;
    }


    public void LoadStudents()
    {
        ObservableCollection<Student> students = new ObservableCollection<Student>();

        students.Add(new Student { FirstName = "Mark", LastName = "Allain" });
        students.Add(new Student { FirstName = "Allen", LastName = "Brown" });
        students.Add(new Student { FirstName = "Linda", LastName = "Hamerski" });

        Students = students;
    }
}
}

这是我的 ViewModelLocator:

using MVVMDemo.ViewModel;

namespace MVVMDemo.VML
{
public class ViewModelLocator
{
private static StudentViewModel studentViewModel = new StudentViewModel();

    public static StudentViewModel StudentViewModel
    {
        get { return studentViewModel; }
    }
}
}

最后这是我的 View 我的 UserControl StudentView

<UserControl
    x:Class="MVVMDemo.Views.StudentView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:MVVMDemo.Views"
    xmlns:vml="using:MVVMDemo.VML"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    DataContext="{Binding Source={StaticResource mainViewModelLocator}, Path=StudentViewModel}"
    d:DesignHeight="300"
    d:DesignWidth="400">  

<!--We will apply MVVM Using ItemTemplates-->
<UserControl.Resources>
    <DataTemplate x:Key = "studentsTemplate">

        <StackPanel Orientation = "Horizontal">
            <TextBox Text = "{Binding Path = FirstName, Mode = TwoWay}" 
        Width = "100" Margin = "3 5 3 5"/>

            <TextBox Text = "{Binding Path = LastName, Mode = TwoWay}" 
        Width = "100" Margin = "0 5 3 5"/>

            <TextBlock Text = "{Binding Path = FullName, Mode = OneWay}" 
        Margin = "0 5 3 5"/>
        </StackPanel>

    </DataTemplate>
</UserControl.Resources>

<Grid>
    <StackPanel Orientation="Horizontal">
        <!--In StudentView.xaml, we need to add SelectedItem property in a ListBox
        which will bind to the SelectStudent property.-->
        <ListView ItemsSource="{Binding Students}" 
                  ItemTemplate="{StaticResource studentsTemplate}"
                  SelectedItem="{Binding SelectedStudent}"/>

        <Button Content = "Delete"  
                Command="{Binding DeleteCommand}"
                HorizontalAlignment = "Left" 
                VerticalAlignment = "Top" 
                Width = "75"/>
    </StackPanel>        
</Grid>
</UserControl>

我在应用程序级别的 app.xaml 文件上应用 viewmodellocator:

<Application.Resources>
    <vml:ViewModelLocator x:Key="mainViewModelLocator"/>
</Application.Resources>

然后我这样调用主页上的 View :

有人可以帮助我吗,我已经在 VS2015 和 VS2017 上运行了这段代码,删除按钮从未被启用,它也没有从 ListView 或列表框中删除行我已经尝试更改它们但似乎没有什么不同。

我什至在不使用此处使用的中继命令模式的情况下进行了命令式实现。 非常感谢您的帮助。

谢谢!!!

最佳答案

编辑:(这不是答案,而是另一种方法)

您知道您可以使用 {x:Bind} 将方法直接绑定(bind)到事件吗?您不需要使用 ICommand

XAML

     <Button Grid.Row="4"
      x:Uid="Send"
      VerticalAlignment="Top"
      HorizontalAlignment="Left"
      MinWidth="80"
      Click="{x:Bind ViewModel.SendFeedback}"/>

代码隐藏

    public async void SendFeedback()
    {
        // Code
    }

用这种方式更容易:)

关于c# - UWP 的 MVVM 模式教程,但它不会绑定(bind)命令,为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43154481/

相关文章:

c# - 我可以通过属性名称设置属性吗?

c# - 使用 C# Windows 窗体进行本地化,无法访问我的 .resx 文件

c# - 导航到另一帧后如何停止 MediaPlayerElement 播放音频?

swift - 无法将 'SharedSequence<DriverSharingStrategy, Data?>'类型的值转换为预期的参数类型

android - 无法解析 DaggerAppComponent

.net - 如何将 Silverlight 2.0 Canvas 保存到数据库并将其导出为 PDF

c# - 带有文化的 MVC5 本地化 - 拥有区域的问题

c# - C# 中的相对路径

c# - 将 char 转换为 int 是 C# 中的安全操作吗?

c# - 文本框不允许我输入小数