MVVM Light: How to get data from usercontrols? - c#

I have a class MyDataCollection that contains MyMetaData and MyData. In my application i have two usercontrolls that display input fields to the user. One for the MyMetaData and the other for MyData. Both usercontrols are included in the MainPage.
My Question is: How should i get the data from the usercontrols then the user klicks on the save-button (located on the mainpage)?
Update
I have changed my code accordingly to blindmeis post but now the MetaDataView is not shown:
<UserControl.Resources>
<DataTemplate x:Key="MetaDataTemplate">
<view:MetaDataView/>
</DataTemplate>
</UserControl.Resources>
<Grid>
<ContentPresenter Content="{Binding MetaDataTemplate}"/>
</Grid>

why not doing mvvm the easy way?(viewmodel first). you say you have a mainpage - this means you also have a mainpageviewmodel. your mainpageviewmodel handles at least the save command. now you want to show MyMetaData and MyData on your mainpage. so the easy way would be to create one MyMetaData instance and one MyData instance in your mainviewmodel.
public class MainPageViewmodel
{
public ICommand SaveCommand { get; set; }
public MyDataViewmodel MyData { get; set; }
public MyMetaDataViewmodel MyMetaData { get; set; }
public MainPageViewmodel()
{
this.MyData = new MyDataViewmodel();
this.MyMetaData = new MyMetaDataViewmodel();
}
}
public class MyDataViewmodel
{}
public class MyMetaDataViewmodel
{}
your mainpage just need 2 datatemplates and 2 contentpresenter.
//resources
<DataTemplate DataType="{x:Type Local:MyDataViewmodel}">
<view:MyDataUserControl/>
</DataTemplate>
<DataTemplate DataType="{x:Type Local:MyMetaDataViewmodel}">
<view:MyMetaDataUserControl/>
</DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ContentPresenter Content="{Binding MyData}" Grid.Column="0"/>
<ContentPresenter Content="{Binding MyMetaData}" Grid.Column="1"/>
<Button Content="Save" Command="{Binding SaveCommand}" Grid.Column="2"/>
</Grid>
because your mainpageviewmodel has both "child" viewmodel, you have all information you want on your savecommand.
if you have another scenario pls update your question, maybe post some code.
EDIT: i have no silverlight so that just a suggestion: maybe rachel can give you a better answer.
<Grid>
<ContentPresenter Content="{Binding MyMetaData}" ContentTemplate="{StaticResource MetaDataTemplate}"/>
</Grid>
if silverlight cant handle datatemplates with datatype you could just put the usercontrol there directly.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<view:MyDataUserControl DataContext="{Binding MyData}" Grid.Column="0"/>
<view:MyMetaDataUserControl DataContext="{Binding MyMetaData}" Grid.Column="1"/>
<Button Content="Save" Command="{Binding SaveCommand}" Grid.Column="2"/>
</Grid>

Since you tagged this question as MVVM, your ViewModels should contain both your SaveCommand and all the data needed to perform the actual save
Your MainViewModel should contain MyMetaData and MyData properties (which are bound to their respective UserControls), and each of those objects should contain properties for any data needed in the UserControl. For example, if your UserControl had a TextBox for Name, then your data object should have a property for the Name that the TextBox binds to.
If the Save button is located in one of those UserControls then the respective ViewModel should have a SaveCommand that gets executed when the Button is clicked. All the data needed for the Save is also located in that ViewModel, so you're good to go.
If your MainViewModel is in charge of saving the data, then it should be able to hook into your sub ViewModel's SaveCommand and attach it's own method, such as
this.MyData.SaveCommand = this.SaveCommand();
and all the data needed for the save can be found in this.MyData
If the SaveButton is located in your MainView, and not in one of the UserControls, then the SaveCommand should be part of MainViewModel, and all the data needed for the save can be found in this.MyData or This.MyMetaData.
Remember, with MVVM your ViewModels are your application. The View is just a pretty interface that allows users to interact with your ViewModels.

You should use Two-way bindings to automatically update the value in your controller. Take a look at this article.
Here's an example:
<TextBox Text="{Binding MyMetaData, Mode=TwoWay }" />
<TextBox Text="{Binding MyData, Mode=TwoWay }" />

I'll give you a little sample, how you can use the MVVM Light Messenger for ViewModel-to-ViewModel communication. Say you have an MyDataCollection class:
public class MyDataCollection
{
public int MyData;
public string MyMetaData;
}
On your MainViewModel you have a RelayCommand (from MVVM light toolkit) binded by your View's SaveButton. When the Connad is executed, you will have to send a Message with a callback action to request data from the subcriber. The callback takes MyDataCollection as parameter:
public class MainViewModel : ViewModelBase
{
public RelayCommand SaveCommand { get; private set; }
//Ctor
public MainViewModel()
{
SaveCommand = new RelayCommand(
() =>
Messenger.Default.Send<NotificationMessageAction<MyDataCollection>>(
new NotificationMessageAction<MyDataCollection>("SaveData", SaveCallback)));
}
private void SaveCallback(MyDataCollection dataCollection)
{
// process your dataCollection...
}
}
The UserControlViewModel has properties the InputTextBoxes are binded too. It just has to register to the message and call the callback with data properties:
public class UserControlViewModel : ViewModelBase
{
//Properties
public string UserControlMetaData { get; set; }
public int UserControlData { get; set; }
//Ctor
public UserControlViewModel()
{
Messenger.Default.Register<NotificationMessageAction<MyDataCollection>>(this, MessageReceived);
}
// private Method to handle all kinds of messages.
private void MessageReceived(MessageBase msg)
{
if(msg is NotificationMessageAction<MyDataCollection>)
{
var actionMsg = msg as NotificationMessageAction<MyDataCollection>;
if(actionMsg.Notification == "SaveData") // Is this the Message, we are looking for?
{
// here the MainViewModels callback is called.
actionMsg.Execute(new MyDataCollection() {MyData = UserControlData, MyMetaData = UserControlMetaData});
}
}
}
}

You will have to use messengers or you will have to set the properties over the ViewModelLocator
Messenger example of how I use it to set the UI language
ViewModel A, I register a listener here with the "SetLanguage" token:
Messenger.Default.Register<string>(this, "SetLanguage", false, input =>
{
SetLanguage(input);
});
ViewModel B, here I send the message with the "SetLanguage" token:
Messenger.Default.Send("en-EN", "SetLanguage");
ViewModelLocator example in ViewModel A, I access data in ViewModel B over the locator:
short value = 12;
var myFilteredDataList = ViewModelLocator.ViewModelBStatic.MyDataList.Any(m => m.code == value);

I have two solutions now:
View:
<ContentPresenter Content="{Binding MyMetaDataView}" />
ViewModel:
public MetaDataViewModel MyMetaDataViewModel { get; set; }
public MetaDataView MyMetaDataView { get; set; }
public MainViewModel()
{
MyMetaDataViewModel = new MetaDataViewModel();
MyMetaDataView = new MetaDataView();
MyMetaDataView.DataContext = MyMetaDataViewModel;
}
or ----
View:
<UserControl.Resources>
<DataTemplate x:Key="MetaDataViewTemplate">
<view:MetaDataView />
</DataTemplate>
</UserControl.Resources>
...
<ContentPresenter Content="{Binding MyMetaDataViewModel}" ContentTemplate="{StaticResource MetaDataViewTemplate}"/>
ViewModel:
public MetaDataViewModel MyMetaDataViewModel { get; set; }
public MainViewModel()
{
MyMetaDataViewModel = new MetaDataViewModel();
}

Related

WPF Main menu for different views / viewmodels

I'd like to create an app, containing the main menu (ribbonmenu) and different usercontrols, each assigned to an own ViewModel.
I was told to not implement classic events in code-behind but to use commands. So far, everything fine, commands for needed methods are implemented.
In my previous approach I "loaded" the UserControl, by assigning the corresponding ViewModel to a ContentControl, that loaded the UserControl, that was assigned to the ViewModel in MainWindow.Resource.
My last approach, simplified with a button instead of a menu:
<Window.Resources>
<DataTemplate x:Name="settingsViewTemplate" DataType="{x:Type viewmodels:SettingsViewModel}">
<views:SettingsView DataContext="{Binding SettingsVM, Source={StaticResource Locator}}"/>
</DataTemplate>
<DataTemplate x:Name="projectsViewTemplate" DataType="{x:Type viewmodels:ProjectViewModel}">
<views:ProjectView DataContext="{Binding ProjectVM, Source={StaticResource Locator}}"/>
</DataTemplate>
</Window.Resources>
<StackPanel>
<Button Content="Load Settings" Height="20" Margin="20 20 20 0" Click="ShowSettings"/>
<ContentControl Margin="5" Height="100" Content="{Binding}"/>
</StackPanel>
simplified code-behind:
public SettingsViewModel settingsViewModel;
public MainWindow()
{
InitializeComponent();
settingsViewModel = new SettingsViewModel();
}
private void ShowSettings(object sender, RoutedEventArgs e)
{
DataContext = settingsViewModel;
}
How can I load a UserControl, using ViewModel commands?
Don't use code-behind to handle view models. A View model should handle view models. Generally the same view model that implements the commands.
First create a main view model for the MainWindow as data source. This view model will also handle the switching between the views. It's recommended to let all page view models implement a common base type e.g. IPage.
Also you don't need any locator for this scenario. The views inside the DataTemplate will automatically have their DataContext set to the data type that maps to the DataTemplate. SettingsView will automatically have SetingsViewModel as the DataContext. If this would be the wrong context, then your model design is wrong.
IPage.cs
interface IPage : INotifyPropertyChanged
{
string PageTitel { get; set; }
}
SettingsViewModel.cs
class SettingsViewModel : IPage
{
...
}
ProjectViewModel.cs
class ProjectViewModel : IPage
{
...
}
PageName.cs
public enum PageName
{
Undefined = 0, SettingsPage, ProjectPage
}
MainViewModel.cs
An implementation of RelayCommand can be found at
Microsoft Docs: Patterns - WPF Apps With The Model-View-ViewModel Design Pattern - Relaying Command Logic
class MainViewModel : INotifyPropertyChanged
{
public ICommand SelectPageCommand => new RelayCommand(SelectPage);
public Dictionary<PageName, IPage> Pages { get; }
private IPage selectedPage;
public IPage SelectedPage
{
get => this.selectedPage;
set
{
this.selectedPage = value;
OnPropertyChanged();
}
}
public MainViewModel()
{
this.Pages = new Dictionary<PageName, IPage>
{
{ PageName.SettingsPage, new SettingsViewModel() },
{ PageName.ProjectPage, new ProjectViewModel() }
};
this.SelectedPage = this.Pages.First().Value;
}
public void SelectPage(object param)
{
if (param is PageName pageName
&& this.Pages.TryGetValue(pageName, out IPage selectedPage))
{
this.SelectedPage = selectedPage;
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
MainWindow.xaml
<Window>
<Window.DataContext>
<MainViewModel />
</Window.DataContext>
<Window.Resources>
<DataTemplate x:Name="settingsViewTemplate" DataType="{x:Type viewmodels:SettingsViewModel}">
<views:SettingsView />
</DataTemplate>
<DataTemplate x:Name="projectsViewTemplate" DataType="{x:Type viewmodels:ProjectViewModel}">
<views:ProjectView />
</DataTemplate>
</Window.Resources>
<StackPanel>
<!-- Content navigation -->
<StackPanel Orientation="Horizontal">
<Button Content="Load Settings"
Command="{Binding SelectPageCommand}"
CommandParameter="{x:Static PageName.SettingsPage}" />
<Button Content="Load Projects"
Command="{Binding SelectPageCommand}"
CommandParameter="{x:Static PageName.ProjectPage}" />
</StackPanel>
<ContentControl Content="{Binding SelectedPage}" />
<StackPanel>
</Window>
The short version:
public class MyViewModel : ViewModel
public MyViewModel()
{
View = new MyUserControlView();
View.DataContext = this; // allow the view to bind to the viewModel.
}
....
public UIElement View {
get; private set;
}
}
And then in XAML:
<ContentControl Content={Binding View} />
There are variations on this theme but that's the basic premise. e.g., if you have a ViewModel that can be bound to multiple views, or ViewModels that have lifetimes longer than their view, you can use a FrameViewModel class like this:
public class FrameViewModel : INotifyProperyChanged; {
public FrameViewModel(IViewModel viewModel; )
{
ViewModel = viewModel;
View = viewModel.CreateView();
View.DataContext = ViewModel;
}
public IViewModel ViewModel { get; set;...}
public UIElement View { get; set; }
}
And then bind THAT into the host XAML with a ContentControl binding to Frame.View.
A more pure approach is to the use the DataTemplateSelector class to instantiate the User Control in a DataTemplate. This is probably the method that WPF designers had in mind for connecting View and ViewModel in WPF. But it ends up spreading the mapping of View and ViewModel across three separate files (the custom C# DataTemplateSelector implementation; widely-separated static resource declaration and ContentControl wrapper in the hosting Window/Page; and the DataTemplate resources themselves which end up in resource files eventually if you have anything but a trivial number of ViewModel/View bindings.
Purists would argue, I suppose, that there's something dirty about having a viewmodel create a view. But there's something far more dirty about code to make DataTemplateSelectors work spread across five files, and inevitable complications with databindings that ensue while trying to tunnel a binding through a DataTemplate.

How do you take input of a TextBox and return it in a TextBlock

I am new to MVVM and I am trying to type a string into a textbox and it return on a textblock on another page.
In my Views folder I have this code in xaml which is the textbox that I want to type into:
<TextBox x:Name="date" Text="{Binding Date}" Grid.Row="0" TextAlignment="Right" TextWrapping="Wrap" Margin="0 10 0 1" Padding="1" />
This is a different wpf page that has the textblock and I want what was typed in the textbox to appear here:
<TextBlock Grid.Row="0" TextAlignment="Right" TextWrapping="Wrap" Margin="0 0 0 2" Padding="1" Text="{Binding Date}" />
In my Model folder I have the class Data Entry which looks like this:
public class DataEntry
{
public string Date { get; set; }
}
In my ViewModels folder I have:
namespace FumeHood1._0._0.ViewModels
{
public class MainViewModel : INotifyPropertyChanged
{
public DataEntry DataEntry { get; set; }
private string date;
public string Date
{
get { return date; }
set
{
date = value;
OnPropertyChanged(nameof(Date));
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
I have been looking everywhere and I cant find the right way to do it. If anyone could help it would be amazing. Just trying to make this MVVM pattern work and make more sense to me.
First, set the DataContext of your view.
public partial class MainWindow : Window
{
public MainWindow() {
InitializeComponent();
DataContext = new MainViewModel();
}
}
Or in xaml : (NOT both at the same time)
<Window>
<Window.DataContext>
<vm:MainViewModel/>
</Window.DataContext>
</Window>
And make sure the same instance of MainViewModel is used in both pages.
Second, carefully configure your bindings to act as intended:
<TextBox Text="{Binding Date, UpdateSourceTrigger=PropertyChanged, Mode=OneWayToSource}"/>
<TextBlock Text="{Binding Date}" />
Note that UpdateSourceTrigger=PropertyChanged makes sure that the view model property is updated while the user types. Mode=OneWayToSource only updates the view model property from the TextBox Text property, but not the other way round.

DataTemplate button command from binding

I'm using Wpf and I'm passing a List<Value> to a <ItemsControl> in the xaml. I would like to bind the string in the Value Object to the Command of a Button. This xaml part looks like this:
<Grid Margin="0,0,2,0">
<Grid Margin="10">
<ItemsControl Name="details">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Margin="0,0,0,5">
<Grid.ColumnDefinitions>
....
</Grid.ColumnDefinitions>
...
<Button Grid.Column="2"
Content="{Binding ButtonContent}"
Visibility="{Binding ButtonVisibility}"
Command="{Binding ButtonClickMethod}" />
...
My Value Class looks like this:
public class Value
{
...
public string ButtonClickMethod { get; set; }
}
I'm setting the string link this:
v.ButtonClickMethod = "RelatedActivityId_OnClick";
And the Method is in the same class and looks like this:
private void RelatedActivityId_OnClick(object sender, RoutedEventArgs e)
{
MessageBox.Show("RelatedActivityId_OnClick");
}
Everything besides this is working properly and unses the same Object for the binding.
What am I doing wrong?
The Command property of the Button is of type ICommand so you cannot bind it to a string value.
You need to update your ButtonClickMethod to be of type ICommand or create a new property to bind you Command to.
See this answer for a sample implementation of ICommand.
If you need the button to execute code based on a parameter (string value?) then you can use the CommandParameter property, then use that paramters in your Command handler.
public class Value
{
public Value()
{
ButtonCommand = new RelayCommand((a) => true, CommandMethod);
}
public RelayCommand ButtonCommand {get; set; }
public string ButtonClickMethod { get; set; }
private void CommandMethod(object obj)
{
MessageBox.Show(obj?.ToString());
}
}
and the XAML:
<Button Grid.Column="2"
Content="{Binding ButtonContent}"
Visibility="{Binding ButtonVisibility}"
Command="{Binding ButtonCommand}"
CommandParameter="{Binding ButtonClickMethod}" />
The Button.Command property binds only to objects which implement the ICommand interface.
If you want to invoke a method which its name is ButtonClickMethod, you will have to:
Create a class which implements ICommand interface.
Create a object of that class and bind it to your button (bind it to Button.Command).
Pass the Value.ButtonClickMethod as a CommandParameter to your ICommand object.
Use this to invoke any method you would like to.

MVVM Binding Observable Collection to view?

In my application, I need to bind a checkbox list to an observable collection. I have seen many examples but I could not find a proper implementation for this and thats why I am posting this question.
The View:
<Grid Name="GrdMain" Background="White">
<ListView Name="lstConditions" VerticalAlignment="Top" Height="150"
ItemsSource="{Binding ConditionsModels}" Margin="0,25,0,0" BorderBrush="Transparent" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox Content="{Binding Path=condition}" Margin="8" Style="{StaticResource CheckBoxDefault}"
IsChecked="{Binding hasCondition,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListView>
</grid>
The model:
public class ConditionsModel
{
public int profileId { get; set; }
public string condition { get; set; }
public bool hasCondition { get; set; }
}
The View Model:
public class ConditionsViewModel : INotifyPropertyChanged
{
private ConditionsModel _conditionsModel;
private ObservableCollection<ConditionsModel> _conditionsModels;
public ConditionsModel ConditionsModel
{
get
{
return _conditionsModel;
}
set
{
_conditionsModel = value;
RaisePropertyChanged("ConditionsModel");
}
}
public ObservableCollection<ConditionsModel> ConditionsModels
{
get
{
return _conditionsModels;
}
set
{
_conditionsModels = value;
RaisePropertyChanged("ConditionsModels");
}
}
public ConditionsViewModel(int profileId)
{
ConditionsModel = new ConditionsModel();
ConditionsModels = new ObservableCollection<ConditionsModel>();
ConditionsModels.CollectionChanged += ConditionsModels_CollectionChanged;
GetConditions(profileId);
}
void ConditionsModels_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
RaisePropertyChanged("ConditionsModels");
}
private void GetConditions(int profileId)
{
HealthAssessmentRepository _rep = new HealthAssessmentRepository();
_conditionsModels = _rep.GetConditions(profileId);
}
}
Is this a correct implementation? I need to update the model when the user checks or unchecks the checkbox. But its not raising the propery changed event when the check box is checked or unchecked.Should I implement the INotifyPropertyChanged interface on the model as well?
I have seen many examples, but all of them has different approaches to this and I am confused. Please show the correct implementation of this?
Thanks
I think you have missed the DataType property within DataTemplate. Just refer this
<DataTemplate DataType="{x:Type sampleApp:ConditionsModel}">
Here sampleApp in the namespace reference created within tag. And ConditionsModel is your model class.
You need to implement INotifyPropertyChanged for class ConditionsModel and raise PropertyChangedEvent for the property you want to observe/synchronize, because it is ViewModel as well.
For class ConditionsViewModel, it's the ViewModel of whole ListView, for ConditionsModel, it's the ViewModel of every line. ViewModel can be overlaid. If ConditionsModel is the domain model, my suggestion is that add a new ItemViewModel, because they belong to different layers. It's always better to distinguish the different layers properly.

How to set a class in the DataContext with XAML?

I have a WPF forms and a class Users (content attributes Id, Login and Name), in my class of this forms, I had get a Users object for put this information in the form with DataContext and Binding
I can put this Users object to my Window.DataContext (this.DataContext = usersObject;) with code behind, but I think if I can make this with XAML, maybe is better
I have set a attribute in my class UserForm (public Users usersObject {get; set;})
My form UserForm : Window
<Window DataContext="{What need I put here?">
<Grid>
<TextBlock Text="Id:"/>
<TextBox Name="Id" Text="{Binding Path=Id}"/>
<TextBlock Text="Login:"/>
<TextBox Name="Login" Text="{Binding Path=Login}"/>
<TextBlock Text="Name:"/>
<TextBox Name="Name" Text="{Binding Path=Name}"/>
</Grid>
</Window>
UserForm.xaml.cs
public class UserForm : Window
{
public Users userObject { get; set; }
public UserForm(Users user)
{
InitializeComponent();
this.userObject = user;
}
}
My class Users
public class Users
{
public int Id { get; set; }
public string Login { get; set; }
public string Name { get; set; }
}
How to I do for set userObject in the itself Window.DataContext for TextBox's can put it values?
Some time back I had written an article on different options of binding XAML control to code behind property. This might help you.
http://codingseason.blogspot.in/2013/05/data-binding-xaml-control-to-property.html
Remove the DataContext binding since you are not explicitly doing MVVM pattern. No point of doing the binding.
In your Window.xaml
<Window>
<Grid>
<TextBlock Text="Id:"/>
<TextBox Name="Id" Text="{Binding Path=Id}"/>
<TextBlock Text="Login:"/>
<TextBox Name="Login" Text="{Binding Path=Login}"/>
<TextBlock Text="Name:"/>
<TextBox Name="Name" Text="{Binding Path=Name}"/>
</Grid>
Add this to your Behind the code Window.xaml.cs
public class UserForm : Window
{
public Users userObject { get; set; }
public UserForm(Users user)
{
InitializeComponent();
this.DataContext = user;
}
}
If you would do it in MVVM you would have done something like this
ViewModel.cs
public class UserViewModel
{
private Users _model;
public UserViewModel(Users model)
{
_model = model;
}
public int Id { get { return _model.Id; } }
public string Login { get { return _model.Login; } set { _model.Login; } }
public string Name { get { return _model.Name; } set { _model.Name; } }
}
Now the ViewModel can be customize depending on what you need, you can expose the Model, inject it to the constructor or just set the property value if it is exposed. Don't forget to implement INotifyPropertyChanged if you want to propagate any values in the ViewModel back to the user interface.
View.xaml.cs
public class UserForm : Window
{
public UserForm(Users user)
{
InitializeComponent();
this.DataContext = new UserViewModel(user);
}
View.xaml
You have two choices, you can explicitly set the DataContext just like what I did behind the code or you can create a public property that returns the UserViewModel. It's just the same
Model.cs
public class Users { //Whatever properties you need }
Now this is a very simplistic example of MVVM pattern. Once you know the basics, you can then integrate some helpful frameworks that implements MVVM for you like Caliburn Micro and MVVM Toolkit
Create an object of UserForm and assigning data context is pretty simple.
UserForm userFormView = new UserForm ();
Users dataContextObject = new Users();
userFormView.DataContext = dataContextObject;
userFormView.Show() //you can also use showdialog. Thats up to you
Its better you remove the following code:
public Users userObject { get; set; }
public UserForm(Users user)
{
InitializeComponent();
this.userObject = user;
}
Its better to separate the view and the viewmodel. Have a look at MVVM and it will make more sense
This is one of the way to assign DataContext directly from xaml.
Example App.xaml
<Application.Resources>
<local:Users x:Key="Users"/>
</Application.Resources>
Example UserForm.xaml
<Window DataContext="{StaticResource Users}">
<Grid>
<TextBlock Text="Id:"/>
<TextBox Name="Id" Text="{Binding Path=Id}"/>
<TextBlock Text="Login:"/>
<TextBox Name="Login" Text="{Binding Path=Login}"/>
<TextBlock Text="Name:"/>
<TextBox Name="Name" Text="{Binding Path=Name}"/>
</Grid>
</Window>
Maybe you can define a DependencyProperty to wrap the access to the userObject,
then bind it to the DataContext

Categories