【问题标题】:How to use the viewmodel, model, command classes with Data Binding in the Window.Resources tags?如何在 Window.Resources 标签中使用带有数据绑定的视图模型、模型、命令类?
【发布时间】:2016-07-12 20:56:41
【问题描述】:

如果 WPF MVVM 应该没有代码,为什么在使用 ICommand 时,是否需要在 Window.xaml.cs 代码中实例化 DataContext 属性?我已经并排观看并关注了 YouTube WPF MVVM、数据绑定、ICommand、INotifyPropertyChanged 视频,我很困惑。

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new ViewModel.VM_CalcRblAmt();
    }
}

如何将视图模型、模型、命令类与数据绑定一起使用 在 Window.Resource 标记中?如果那是正确的 mvvm 模式? Window.Resource 标记中的以下内容(但不起作用)? 我问这个是因为在不同作者的 WPF MVVM 教程上并排看,我看不到如何将视图模型、模型和命令类插入 UI 中的 xml 命名空间(在本例中为窗口)。例如下面:

<Window...
         xmlns:nsviewmodel="clr-namespace:Wpf_MVVVM_Rbr.ViewModel" />
<Window.Resources>
<nsrbrvm:RbrCoreViewModel x:Key="objRbrTemp"
  <Button x:Name="btnRebalancer" 
     Command="{Binding CalcRbrAmtCommand}" 
     Content="Rebalance"/>
  <TextBox x:Name="txtAmtDaily" Text="{Binding model_Rblr_Temp.AmtDaily, UpdateSourceTrigger=PropertyChanged}" />
</Window.Resources>

同样,上面的代码实际上并不在 Window.Resources 之间 目前的标签。它位于 Window.Resources 标记之外的 UI XAML 代码中。目前确实工作。但是 MVVM 模式是否不需要在 Window.Resources 或 Page.Resources 标签中引用 xmlns 命名空间并为其赋予 x:Key="someKeyName" 并在 Resources 标签内使用数据绑定?

如果这正确的 MVVM 实践,我如何使用数据绑定将 Window.Resources 数据绑定、视图模型、命令和模型类放在一起?

提前致谢! 真挚地, 我

【问题讨论】:

  • “应该没有后面的代码”并不意味着后面有个代码;这意味着尽可能少。
  • 确实如此。目标是避免代码隐藏,但不删除它。在工作中,我们避免使用事件处理程序等来支持附加属性和混合行为,但是对于几乎每个对话框,我们最终都会更改构造函数以将 ViewModel 作为唯一参数传递给对话框。并非所有代码隐藏都是不好的,但我们确实会积极尝试将其最小化。
  • 我同意 WPF 中的代码隐藏在很多情况下少即是多,但这并不意味着完全消除它。标记的用处要多得多,但这里的相关部分之一是它大大减少了代码量,例如妨碍您关注的逻辑的字段。 WPF 中 Xaml 文件的使用非常类似于 C++ 中的头文件。

标签: wpf mvvm data-binding routed-commands xaml-resources


【解决方案1】:

1.如果 WPF MVVM 应该没有代码背后,为什么在使用 ICommand 时,是否需要在 Window.xaml.cs 代码中实例化 DataContext 属性? 设置DataContext的方法有很多:

第一种方法。鉴于:

<Window.DataContext>
   <local:MainWindowViewModel/>
</Window.DataContext>

第二种方法。您应该重写 App.xaml.cs 的 OnStartUp() 方法

public partial class App : Application
{
     protected override void OnStartup(StartupEventArgs e)
    {
            base.OnStartup(e);
            MainWindow app = new MainWindow();
            ProductViewModel context = new ProductViewModel();
            app.DataContext = context;
            app.Show();
     }
}

第三种方法。在Windows的构造函数中:

public partial class MainWindow : Window
{
     public MainWindow()
     {
          InitializeComponent();
          DataContext=new MainWindowViewModel();
     }
}

第四种方式。可以通过UnityContainer的DependencyInjection来设置DataContext。但是 DependencyInjection、Prism 和 UnityContainer 是其他问题,并且超出了这个问题的范围。举个例子:

protected override void RegisterTypes()
{ 
    unityContainer.RegisterType<object, ItemControl>("ModuleAUpper");
    unityContainer.RegisterType<IViewModelItemControl, ViewModelItemControl>();
    unityContainer.RegisterTypeForNavigation<ItemControl>();
}

2.如何在 Window.Resource 标签中使用带有数据绑定的视图模型、模型、命令类?如果那是正确的 mvvm 模式? Window.Resource 标记中的以下内容(但不起作用)?

Resources are just chance to store data. 要设置 viewModel 和 XAML 中的属性之间的绑定,您应该:

private string message="helloWorld";    

public string Message
{
    get { return message;}
    set { message = value;}
}

和 XAML:

在 MVVM 范围内绑定Button

<Button Command="{Binding ClickCommand}" Width="100" Height="100" Content="wefwfwef"/>

和 ViewModel:

private ICommand _clickCommand;
public ICommand ClickCommand
{
   get
   {
     return _clickCommand ?? (_clickCommand = new CommandHandler(() => MyAction(), _canExecute));
   }
}
private bool _canExecute;

public class CommandHandler : ICommand
{
  private Action _action;
  private bool _canExecute;
  public CommandHandler(Action action, bool canExecute)
  {
      _action = action;
      _canExecute = canExecute;
  }

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

  public event EventHandler CanExecuteChanged;

  public void Execute(object parameter)
  {
     _action();
  }
}

更新:

我建议你阅读我读过的最好的MVVM tutorial by Rachel Lim

【讨论】:

  • 谢谢StepUp。在我对代码进行逆向工程后,我会更详细地评论。
【解决方案2】:

谢谢,StepUp!

您的答案的第一部分我得到了第一和第二的工作!我正在使用第一种方法来避免后面的任何代码。第三个我肯定会工作,只是也许我错过了你认为我知道的东西。但是方法一是我想要的!谢谢。当我熟悉该类时,我会花一些时间尝试使用和理解方法 4,UnityContainer.Registry 类型。 您赞赏的答案,问题的第 2 部分,我还没有逆向工程和应用。通过 ICommand 接口,我一直在使用 ICommand 以及从 YouTube 教程视频中获取的内容。但是,一旦我使用您的代码,我会回来感谢您。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-29
    • 2012-06-16
    • 2022-01-09
    • 2012-10-02
    • 2018-06-20
    • 1970-01-01
    相关资源
    最近更新 更多