2

一般来说,我对 C# 和 WPF 很陌生,来自 LAMP Web 应用程序背景。我已经尝试过几个关于这个主题的教程,但它们让我很困惑。

https://rachel53461.wordpress.com/2011/05/08/simplemvvmexample/ http://www.codeproject.com/Articles/165368/WPF-MVVM-Quick-Start-Tutorial

在第一个教程中,应用程序以一个简单的界面打开。一个文本框和两个按钮。当您更新 ProductId 文本框时,从 0 变为 1,“获取产品”按钮变为活动状态。当您单击“获取产品”按钮时,会出现 DataTemplate 的内容。我看不到这些事情实际发生在哪里。是什么导致按钮变为活动状态?是什么导致表格出现?

希望你们能帮我把它变笨=)

4

3 回答 3

4

按钮被激活或停用,因为它们绑定到ICommand. ICommand包括一个CanExecute属性,该属性确定按钮是否处于活动状态。

我看不到这些事情实际发生在哪里。

该命令使用委托:

 _getProductCommand = new RelayCommand(
                param => GetProduct(),
                param => ProductId > 0
            );

第二个委托使命令在(委托返回 true CanExecute)时被激活(变为 true )。ProductId > 0

当您单击按钮时,命令的Execute方法将触发并执行操作。

至于首先启动的窗口,请查看标题为“启动示例”的部分 -app.xaml.cs其中有用于首先显示窗口的代码。

于 2013-04-16T17:22:58.590 回答
1

在该特定示例中,您可以看到:

<TextBox Grid.Row="0" Grid.Column="1" Text="{Binding ProductId}" />

使用数据绑定TextBox将其属性绑定到当前数据上下文(这是视图模型的实例)上。TextProductId

当您在 中键入文本时TextBox,其值将ProductId在视图模型的属性上自动更新。

该命令检查 的值ProductId是否大于 0 以确定是否Button启用。

可以看到Button' 命令设置为GetProductCommand:

<Button ... Command="{Binding Path=GetProductCommand}" ... />

使用GetProductCommand表达式ProductId > 0作为其CanExecute谓词:

_getProductCommand = new RelayCommand(
              param => GetProduct(),
              param => ProductId > 0
);

WPF 将执行此 lambda 表达式ProductId > 0,其结果将确定是否Button启用。启用并单击按钮后,将执行第一个 lambda 表达式 - GetProduct()

说了这么多,你真的应该使用 MVVM 框架,这些框架还有其他机制可以在你的视图模型上调用方法,这些机制克服了命令的一些限制。

于 2013-04-16T17:25:34.993 回答
1

本质上,MVVM 或 Model、View、ViewModel 背后的理念是删除背后的代码并分离出应用程序的各个层,以便它们可以独立工作。您的 GUI 或视图与 Viewmodel 或代码隐藏之间的交互并没有像您想象的那样发生。很多人对视图模型如何与 gui 或视图进行交互感到困惑。我是一名 winforms 开发人员,拥有代码隐藏文件,您可以在其中轻松查看隐藏代码中的事件处理程序并在逻辑上遵循代码。在您将 XAML gui 的数据上下文设置为视图模型的 MainWindow 代码中,如下所示。

public partial class MainWindow : Window
{
    #region Members
    SongViewModel _viewModel;
    int _count = 0;
    #endregion

    public MainWindow()
    {
        InitializeComponent();

        //  We have declared the view model instance declaratively in the xaml.
        //  Get the reference to it here, so we can use it in the button click event.
        _viewModel = (SongViewModel)base.DataContext;
    }

    private void ButtonUpdateArtist_Click(object sender, RoutedEventArgs e)
    {
        ++_count;
        _viewModel.ArtistName = string.Format("Elvis ({0})", _count);
    }
}    

然后 {Binding Path=Property} 将 _viewModel 的属性连接到 XAML 元素。添加 RaisePropertyChanged 是通知 gui 该属性的值已更改。

public string ArtistName
    {
        get { return Song.ArtistName; }
        set
        {
            if (Song.ArtistName != value)
            {
                Song.ArtistName = value;
                RaisePropertyChanged("ArtistName");
            }
        }
    }

View 模型的 ArtistName 属性绑定到标签,就像在 XAML 中一样

这或多或少是您在 gui 和代码之间的交流。因此,例如在您的第一个示例中,当您将文本框从 0 更改为 1 时,就会更新 ViewModel 中的 ProductID 属性。您可以在您的 ICommand GetProductCommand 中看到有一个参数被传递给 relayCommand 用于 ProductID > 0。现在它的 1 canexecute 为真,因此该命令现在可以执行并且按钮变为可点击。当您单击它时,GetProduct 是发生的操作,然后该方法将您的 CurrentProduct 属性设置为值。产品信息的 Datatemplate 绑定到 xaml 中的 ProductModel,ProductModel 绑定到 CurrentProduct,因此现在在该数据模板中 CurrentProduct 的属性可以绑定到 xaml 元素,因此 CurrentProduct.ProductName 或绑定到

<TextBox Grid.Row="1" Grid.Column="1"  Text="{Binding ProductName}" />

起初它令人困惑,但当你掌握它时,它会完全有意义。

于 2013-04-16T18:11:15.230 回答