Как использовать 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. Но я вернусь сюда, чтобы поблагодарить вас, как только я введу ваш код в действие.