在WPF MVVM中,此按钮单击如何工作? [英] How does this button click work in WPF MVVM?

查看:32
本文介绍了在WPF MVVM中,此按钮单击如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开始研究WFM MVVM模式.

I'm starting to study about WFM MVVM pattern.

但是我不明白为什么 Button 单击没有绑定任何事件或动作就可以起作用.

But I can't understand why this Button click works without binding any event or action.

查看

<Window x:Class="WPF2.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:vm="clr-namespace:WPF2.ViewModel"
    Title="MainWindow" Height="350" Width="525">

    <Window.Resources>
        <vm:MainWindowViewModel x:Key="MainViewModel" />
    </Window.Resources>

    <Grid x:Name="LayoutRoot"
          DataContext="{Binding Source={StaticResource MainViewModel}}">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>

        <TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,7,0,0" Name="txtID" VerticalAlignment="Top" Width="178" Text="{Binding ElementName=ListViewProducts,Path=SelectedItem.ProductId}" />
        <TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,35,0,0" Name="txtName" VerticalAlignment="Top" Width="178" Text="{Binding ElementName=ListViewProducts,Path=SelectedItem.Name}" />
        <TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,61,0,0" Name="txtPrice" VerticalAlignment="Top" Width="178" Text="{Binding ElementName=ListViewProducts,Path=SelectedItem.Price}" />
        <Label Content="ID" Grid.Row="1" HorizontalAlignment="Left" Margin="12,12,0,274" Name="label1" />
        <Label Content="Price" Grid.Row="1" Height="28" HorizontalAlignment="Left" Margin="12,59,0,0" Name="label2" VerticalAlignment="Top" />
        <Label Content="Name" Grid.Row="1" Height="28" HorizontalAlignment="Left" Margin="12,35,0,0" Name="label3" VerticalAlignment="Top" />

        <Button Grid.Row="1" HorizontalAlignment="Left" VerticalAlignment="Top" Width="141" Height="23" Margin="310,40,0,0" Content="Update" />

        <ListView Name="ListViewProducts" Grid.Row="1" Margin="4,109,12,23"  ItemsSource="{Binding Path=Products}"  >
            <ListView.View>
                <GridView x:Name="grdTest">
                    <GridViewColumn Header="Product ID" DisplayMemberBinding="{Binding ProductId}" Width="100"/>
                    <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" Width="250" />
                    <GridViewColumn Header="Price" DisplayMemberBinding="{Binding Price}" Width="127" />
                </GridView>
            </ListView.View>
        </ListView>
    </Grid>
</Window>

ViewModel

class MainWindowViewModel : INotifyPropertyChanged
{
    public const string ProductsPropertyName = "Products";

    private ObservableCollection<Product> _products;

    public ObservableCollection<Product> Products
    {
        get
        {
            return _products;
        }
        set
        {
            if (_products == value)
            {
                return;
            }

            _products = value;
            RaisePropertyChanged(ProductsPropertyName);
        }
    }

    public MainWindowViewModel()
    {
        _products = new ObservableCollection<Product>
        {
            new Product {ProductId=1, Name="Pro1", Price=11},
            new Product {ProductId=2, Name="Pro2", Price=12},
            new Product {ProductId=3, Name="Pro3", Price=13},
            new Product {ProductId=4, Name="Pro4", Price=14},
            new Product {ProductId=5, Name="Pro5", Price=15}
        };
    }

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    public void RaisePropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    #endregion
}

我从我阅读的教程中找到了这段代码.当我单击列表视图中的一行时,将设置文本框值.当我编辑这些值并单击一个按钮时,列表视图上的值将更新.

I found this code from a tutorial i've read. When i click on a row from listview, the textbox values are set. And when I edit those values and click a button, the values on listview are updated.

按钮上没有事件或命令.那么如何单击按钮以更新列表视图中的值?

There is no event nor command bound on the button. So how do button click update the values from listview??

推荐答案

我知道这很旧,但是我正在研究这种情况并找到了答案.首先,在MVVM理论中,隐藏代码"不应该包含代码,所有代码都应位于ViewModel类中.因此,为了实现按钮单击,您需要在ViewModel中包含以下代码(除了INotifyPropertyChanged实现之外):

I know this is old but I was looking into this scenario and found my answer. First, in MVVM theory the "code-behind" shouldn't have code all the code should be in the ViewModel class. So in order to implement button click, you have this code in the ViewModel (besides the INotifyPropertyChanged implementation):

        public ICommand ButtonCommand { get; set; }

        public MainWindowViewModel()
        {
            ButtonCommand = new RelayCommand(o => MainButtonClick("MainButton"));
        }

        private void MainButtonClick(object sender)
        {
            MessageBox.Show(sender.ToString());            
        }

使用课程:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;

namespace <your namespace>.ViewModels
{
    public class RelayCommand : ICommand
    {
        private readonly Action<object> _execute;
        private readonly Predicate<object> _canExecute;

        public RelayCommand(Action<object> execute, Predicate<object> canExecute = null)
        {
            if (execute == null) throw new ArgumentNullException("execute");

            _execute = execute;
            _canExecute = canExecute;
        }

        public bool CanExecute(object parameter)
        {
            return _canExecute == null || _canExecute(parameter);
        }

        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; } 
            remove { CommandManager.RequerySuggested -= value; }
        }

        public void Execute(object parameter)
        {
            _execute(parameter ?? "<N/A>");
        }

    }
}

在XAML中:

<Window.DataContext>
    <viewModels:MainWindowViewModel />
</Window.DataContext>  <Button Content="Button"  Command="{Binding ButtonCommand}"  />

这篇关于在WPF MVVM中,此按钮单击如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆