Как использовать viewmodel, модель, классы команд с привязкой данных в тегах Window.Resources?

Если предполагается, что WPF MVVM не имеет кода позади, почему при использовании ICommand вам нужно свойство DataContext, созданное в коде Window.xaml.cs? Я смотрел и следил рядом с 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 от разных авторов, я не вижу, как подключить модель представления, модель и классы Command к пространству имен xml в пользовательском интерфейсе (в данном случае Window). Например, ниже:

<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. Он находится в коде пользовательского интерфейса XAML вне тегов Window.Resources. Который в настоящее время работает. Но разве шаблон MVVM не требует его в тегах Window.Resources или Page.Resources, ссылающихся на пространство имен xmlns и предоставляющих ему x:Key="someKeyName" и использующих привязку данных внутри тегов Resources?

Так что, если это правильная практика MVVM, как соединить привязку данных Window.Resources, модель представления, команды и классы моделей вместе, используя привязку данных?

Заранее спасибо! С уважением, я

2 ответа

1. Если предполагается, что WPF MVVM не имеет кода позади, почему при использовании ICommand вам нужно свойство DataContext, которое создается в коде Window.xaml.cs? Существует много подходов для установки DataContext:

Первый подход. Ввиду:

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

Второй подход. Вы должны переопределить метод OnStartUp() в App.xaml.cs

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();
     }
}

Четвертый подход. Вы можете установить DataContext через DependencyInjection от UnityContainer. Но 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?

Ресурсы - это просто шанс хранить данные. Чтобы установить привязку между свойством, размещенным в viewModel и XAML, вам необходимо:

private string message="helloWorld";    

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

и XAML:

переплет 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 Рэйчел Лим, которое я когда-либо читал.

Спасибо, StepUp!

Часть первая вашего ответа я получил 1-го и 2-го на работу! Я использую 1-й подход, чтобы избежать какого-либо кода позади. Третий, я уверен, сработает, просто, может быть, я чего-то упускаю, что вы предположили, что я знал. Но первый подход - это то, что я искал! Благодарю. Когда-нибудь я попытаюсь использовать и понять подход 4, тип UnityContainer.Registry, когда познакомлю себя с этим классом. Часть 2 вашего благодарного ответа, вопрос, который я еще не разработал и не применил. С интерфейсом ICommand я использую ICommand с тем, что я взял из учебного видео youTube. Но я вернусь сюда, чтобы поблагодарить вас, как только я введу ваш код в действие.

Другие вопросы по тегам