此按钮单击在 WPF MVVM 中如何工作?

2023-11-21

我开始研究WFM MVVM模式。

但我不明白为什么会这样Buttonclick 无需绑定任何事件或操作即可工作。

View

<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>

视图模型

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
}

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

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


我知道这已经很旧了,但我正在研究这个场景并找到了答案。 首先,在 MVVM 理论中,“代码隐藏”不应该有代码,所有代码都应该在 ViewModel 类中。 因此,为了实现按钮单击,您可以在 ViewModel 中添加以下代码(除了 INotifyPropertyChanged 实现之外):

        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}"  />
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

此按钮单击在 WPF MVVM 中如何工作? 的相关文章

  • 在 xaml 中编写嵌套类型时出现设计时错误

    我创建了一个用户控件 它接受枚举类型并将该枚举的值分配给该用户控件中的 ComboBox 控件 很简单 我在数据模板中使用此用户控件 当出现嵌套类型时 问题就来了 我使用这个符号来指定 EnumType x Type myNamespace
  • 根据属性的类型使用文本框或复选框

    如果我有这样的结构 public class Parent public string Name get set public List
  • 在一个数据访问层中处理多个连接字符串

    我有一个有趣的困境 我目前有一个数据访问层 它必须与多个域一起使用 并且每个域都有多个数据库存储库 具体取决于所调用的存储过程 目前 我只需使用 SWITCH 语句来确定应用程序正在运行的计算机 并从 Web config 返回适当的连接字
  • 通过引用传递 [C++]、[Qt]

    我写了这样的东西 class Storage public Storage QString key const int value const void add item QString int private QMap
  • 如何从 Visual Studio 将视图导航到其控制器?

    问题是解决方案资源管理器上有 29 个项目 而且项目同时具有 ASP NET MVC 和 ASP NET Web 表单结构 在MVC部分中 Controller文件夹中有大约100个子文件夹 每个文件夹至少有3 4个控制器 视图完全位于不同
  • 如何从本机 C(++) DLL 调用 .NET (C#) 代码?

    我有一个 C app exe 和一个 C my dll my dll NET 项目链接到本机 C DLL mynat dll 外部 C DLL 接口 并且从 C 调用 C DLL 可以正常工作 通过使用 DllImport mynat dl
  • 如何在 C++ 中标记字符串?

    Java有一个方便的分割方法 String str The quick brown fox String results str split 在 C 中是否有一种简单的方法可以做到这一点 The 增强分词器 http www boost o
  • 方程“a + bx = c + dy”的积分解

    在等式中a bx c dy 所有变量都是整数 a b c and d是已知的 我如何找到整体解决方案x and y 如果我的想法是正确的 将会有无限多个解 由最小公倍数分隔b and d 但我只需要一个解决方案 我可以计算其余的 这是一个例
  • C# 列表通用扩展方法与非通用扩展方法

    这是一个简单的问题 我希望 集合类中有通用和非通用方法 例如List
  • VisualStateManager 和生成的转换

    正当我以为我明白的时候VisualStateManager 有些事情证明我错了 我正在使用 WPF 4 并且尝试简单地在鼠标悬停时放大某个项目 并在鼠标离开时将其缩小 我想我只需定义每个状态VisualStateGroup然后指定一个Vis
  • WcfSvcHost 的跨域异常

    对于另一个跨域问题 我深表歉意 我一整天都在与这个问题作斗争 现在已经到了沸腾的地步 我有一个 Silverlight 应用程序项目 SLApp1 一个用于托管 Silverlight SLApp1 Web 的 Web 项目和 WCF 项目
  • C# - 当代表执行异步任务时,我仍然需要 System.Threading 吗?

    由于我可以使用委托执行异步操作 我怀疑在我的应用程序中使用 System Threading 的机会很小 是否存在我无法避免 System Threading 的基本情况 只是我正处于学习阶段 例子 class Program public
  • 实例化类时重写虚拟方法

    我有一个带有一些虚函数的类 让我们假设这是其中之一 public class AClassWhatever protected virtual string DoAThingToAString string inputString retu
  • LINQ:使用 INNER JOIN、Group 和 SUM

    我正在尝试使用 LINQ 执行以下 SQL 最接近的是执行交叉联接和总和计算 我知道必须有更好的方法来编写它 所以我向堆栈团队寻求帮助 SELECT T1 Column1 T1 Column2 SUM T3 Column1 AS Amoun
  • 如何在 Linq to SQL 中使用distinct 和 group by

    我正在尝试将以下 sql 转换为 Linq 2 SQL select groupId count distinct userId from processroundissueinstance group by groupId 这是我的代码
  • C# 中的 IPC 机制 - 用法和最佳实践

    不久前我在 Win32 代码中使用了 IPC 临界区 事件和信号量 NET环境下场景如何 是否有任何教程解释所有可用选项以及何时使用以及为什么 微软最近在IPC方面的东西是Windows 通信基础 http en wikipedia org
  • C++ 继承的内存布局

    如果我有两个类 一个类继承另一个类 并且子类仅包含函数 那么这两个类的内存布局是否相同 e g class Base int a b c class Derived public Base only functions 我读过编译器无法对数
  • 当文件流没有新数据时如何防止fgets阻塞

    我有一个popen 执行的函数tail f sometextfile 只要文件流中有数据显然我就可以通过fgets 现在 如果没有新数据来自尾部 fgets 挂起 我试过ferror and feof 无济于事 我怎样才能确定fgets 当
  • C# 中最小化字符串长度

    我想减少字符串的长度 喜欢 这串 string foo Lorem ipsum dolor sit amet consectetur adipiscing elit Aenean in vehicula nulla Phasellus li
  • Mono 应用程序在非阻塞套接字发送时冻结

    我在 debian 9 上的 mono 下运行一个服务器应用程序 大约有 1000 2000 个客户端连接 并且应用程序经常冻结 CPU 使用率达到 100 我执行 kill QUIT pid 来获取线程堆栈转储 但它总是卡在这个位置

随机推荐

  • 如何从谷歌日历获取活动详细信息

    当日历中创建新事件时 我成功地将谷歌日历的推送通知发送到我的系统中 推送通知的 POST 正文中没有数据 POST 标头如下 Host gt xxxxxx xxxx com Content Type gt application json
  • 实现 ICloneable 时是否应该提供深度克隆?

    我不清楚MSDN 文档在实现 ICloneable 时我是否应该提供深克隆或浅克隆 首选方案是什么 简短回答 是的 长答案 不要使用 ICloneable 这是因为 Clone 没有定义为浅克隆或深克隆 您应该实现自己的 IClone 接口
  • 两个指针指向同一个地址[关闭]

    很难说出这里问的是什么 这个问题模棱两可 含糊不清 不完整 过于宽泛或言辞激烈 无法以目前的形式合理回答 如需帮助澄清此问题以便重新打开 访问帮助中心 当两个指针指向同一个地址时会发生什么 这会导致安全问题吗 事实本身没问题 但是如果你调用
  • 尝试在空对象引用上调用虚拟方法“void android.support.v4.view.ViewPager.setAdapter(android.support.v4.view.PagerAdapter)”

    我正在尝试使用 Android 材料设计来实现滑动选项卡布局 但它给了我NullPointerException 到目前为止 这是我的代码 MainActivity java public class MainActivity extend
  • 在 Matlab 中强制用户输入整数的最佳方法

    我正在 Matlab 中编写一个简单的程序 并且想知道确保用户输入的值是正确整数的最佳方法 我目前正在使用这个 while num dice lt 1 isempty num dice num dice input Enter the nu
  • 如何使用 Keras TensorBoard 回调进行网格搜索

    I m using the Keras TensorBoard callback I would like to run a grid search and visualize the results of each single mode
  • Facebook 连接、电子邮件地址?

    当您添加 facebook connect 以允许 facebook 用户登录您的网站时 您可以撤销用户名和电子邮件地址吗 是的 您需要首先提示他们提供数据权限 电子邮件 Facebook 也在很快改变你访问私人数据的方式 天哪 他们每天都
  • 如何获取 Spark 数据框以将其解释计划打印为字符串

    我有一个系统 其中组件A将sql传递给组件B 然后B通过apache Spark运行sql 并返回结果 出于调试目的 我放置了第二个通信通道 A 可以将 sql 传递给 B 并请求和解释计划 B 中的代码如下所示 def handleExp
  • 使用Python识别监听端口

    在从 bash 翻译一些脚本时 我遇到了许多使用 netstat an 来查找我们的服务之一是否正在侦听的情况 虽然我知道我可以只使用 subprocess call 或其他甚至 popen 我宁愿使用 pythonic 解决方案 所以我没
  • 对于登录 GET 还是 POST? [复制]

    这个问题在这里已经有答案了 我想知道我使用哪种 HTTP 方法来开发登录 API GET 还是 POST 我已经使用 post 方法在 PHP 中开发了登录 API 但是我的老板说 为什么你使用 POST 方法而不是 GET 方法 Alwa
  • 跨线程操作无效:从创建它的线程以外的线程访问控制“label1”[重复]

    这个问题在这里已经有答案了 可能的重复 为什么我会收到此错误 跨线程操作无效 控制 lbFolders 从创建它的线程以外的线程访问 我是 winforms 的新手 在我的代码中 我正在使用 for 循环更新进度条 现在我需要更新循环计数表
  • 在方法(Java 中)中改变对象参数是一种不好的做法吗?

    我有一个关于改变方法中的方法参数 它们是对象 的问题 我多次阅读和听到 在作为参数传入的方法中改变对象是一种不好的做法 例如 public void modifyList List list list add new Object 相反 应
  • jQuery 单击文档事件但忽略 div

    我正在使用 jQuery 制作在线幻灯片 我使用 document click 事件来检测用户何时单击页面 以了解何时显示幻灯片中的下一个项目符号点或移至下一页 我遇到的问题是我的工作让我在页面底部插入一个评论框 当有人单击评论框或保存评论
  • 使用 openssl 链接编译 Qt5 时出错

    我的头很快就会爆炸 我想用 openssl linked 编译 qt 以便 openssl 库链接到 qt 库中 我已经尝试了很多选项 编译时的输出始终是 ssl qsslcertificate openssl cpp In functio
  • Thymeleaf th:href 参数中的条件

    所以我的 Thymeleaf 模板中有一个元素 其中有一个如下所示的链接 th href search searchType parameter1 parameter1 parameter10 parameter10 根据目前的实施情况pa
  • 为什么在 JavaScript 中使用 {} != ( {} )?

    众所周知 是定义对象的更短方法 例如 用于数组 但现在我想知道为什么 计算结果为未定义 评估为 正确 对象 为什么 JavaScript 会有这样的行为 例如1等于 1 所以为什么 不等于 这是一个语法错误 语法错误 意外的标记 就是这样暧
  • 如何从目录中获取子文件夹中的文件

    您好 我必须从目录中的指定路径获取文件 这是我写的方法 但我没有从子文件夹中获取文件 Private void getfiles Directoryinfo info new Directoryinfo configurationmanag
  • 完全覆盖的代码的 EclEmma 覆盖率是否可以低于 100%?

    我只是编写了一些简单的示例代码来确保我正确安装了 EclEmma 我没有获得 100 的覆盖率 我不明白为什么 突出显示意味着它与类名有关 这是我的代码 以及相应的 JUnit 测试 EclEmma 突出显示了它 覆盖率结果显示 三个指令A
  • Tkinter grid_forget 正在清除框架

    from tkinter import from PIL import ImageTk Image root Tk root title Image Viewer def buttonforward image number global
  • 此按钮单击在 WPF MVVM 中如何工作?

    我开始研究WFM MVVM模式 但我不明白为什么会这样Buttonclick 无需绑定任何事件或操作即可工作 View