Quote:
Model–View–ViewModel (MVVM) is a software architectural pattern.
MVVM facilitates a separation of development of the graphical user interface – be it via a markup language or GUI code – from development of the business logic or back-end logic (the data model). The view model of MVVM is a value converter,[1] meaning the view model is responsible for exposing (converting) the data objects from the model in such a way that objects are easily managed and presented. In this respect, the view model is more model than view, and handles most if not all of the view's display logic.[1] The view model may implement a mediator pattern, organizing access to the back-end logic around the set of use cases supported by the view.
ref:
Model–view–viewmodel - Wikipedia[
^]
WPF makes this possible via
Data Binding[
^].
I am an independent software developer and I find the MVVM pattern, along with MEF, a very useful pattern to adhere to.
However, it sounds like you don't want to use the MVVM pattern but want to use the data binding system. That is fine too. Here is an example of using Data Binding without the MVVM Pattern:
XAML Page:
<Window x:Class="WpfSimpleBinding.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
mc:Ignorable="d"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfSimpleBinding"
Title="Basic code-behin binding example"
WindowStartupLocation="CenterScreen" Height="400" Width="300">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.Resources>
<DataTemplate DataType="{x:Type local:PersonModel}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Name}" Margin="10 3"/>
<TextBlock Text="{Binding Age}" Margin="10 3"
Grid.Column="1"/>
</Grid>
</DataTemplate>
</Grid.Resources>
<ListBox ItemsSource="{Binding Persons}">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
<Button Content="Randomize" Padding="10 5" Margin="10"
HorizontalAlignment="Center" VerticalAlignment="Center"
Grid.Row="1" Click="Button_Click"/>
</Grid>
</Window>
Base
INotifyPropertyChanged
implementation (reusable):
public abstract class ObservableBase : INotifyPropertyChanged
{
public void Set<TValue>(ref TValue field, TValue newValue, [CallerMemberName] string propertyName = "")
{
if (EqualityComparer<TValue>.Default.Equals(field, default(TValue)) || !field.Equals(newValue))
{
field = newValue;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
Data Model:
public class PersonModel : ObservableBase
{
private string name;
public string Name
{
get { return name; }
set { Set(ref name, value); }
}
private int age;
public int Age
{
get { return age; }
set { Set(ref age, value); }
}
}
and the Code-Behind for the XAML Page:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = this;
Mock();
}
public ObservableCollection<PersonModel> Persons { get; set; }
= new ObservableCollection<PersonModel>();
private Random rand = new Random();
private void Mock()
{
for (int i = 0; i < 10; i++)
{
Persons.Add(new PersonModel
{
Name = string.Format("Person {0}", i),
Age = rand.Next(20, 50)
});
}
}
private void Button_Click(object sender, RoutedEventArgs e)
{
foreach (var person in Persons)
{
person.Age = rand.Next(20, 50);
}
}
}
We are using traditional (winform style) control events with WPF Data Binding. The downside of this, that the MVVM pattern resolves, is that the code-behind (ViewModel) is tightly bound to the XAML page and controls.