Reputation: 111
I'm new in WPF, but trying to learn it hard, as much as I can. Please help me overcome a problem I'm struggling with right now. I'm building a multitab UI, in which each tab supposed to have exactly the same control layout. In the same time inside a tab there is also repetitive chunk of controls (groups of labels). Controls' content will be filled by data coming from external source - apparently I'll use instances of data object to bind them to tabitem's DataContext property: one instance per tab item. My problem is, I can't figure out how to optimize the code by using templates. I think I should use 2 different templates, one inside the tab and another for whole tab, right? But how to bind the data then? Below the xaml markup I'm going to use for each tab and code-behind, so you can get the idea. The labels with numerical content should be bound to the properties of object instances (PLC).
XAML:
<Window x:Class="WpfPromholComplementary_1.Window2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:loc = "clr-namespace:WpfPromholComplementary_1"
xmlns:wfi="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"
xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
xmlns:dvc="clr-namespace:System.Windows.Forms.DataVisualization.Charting;assembly=System.Windows.Forms.DataVisualization"
Title="Window2" Height="800" Width="1000">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition Height="210" />
<RowDefinition Height="30" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Border Grid.Row="1" Grid.Column="0" BorderThickness="1" BorderBrush="Blue" Margin="2" CornerRadius="8,8,8,8">
<Grid Background="LightCyan">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="10" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="10" />
</Grid.RowDefinitions>
<Label Content="Module 1" Grid.Row="1" Grid.ColumnSpan="2" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="123.4" Grid.Row="2" Grid.Column="1" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="123.4" Grid.Row="3" Grid.Column="1" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="123.4" Grid.Row="4" Grid.Column="1" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="123.4" Grid.Row="5" Grid.Column="1" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="Channel 1:" Grid.Row="2" Grid.Column="0" Height="Auto" Width="Auto" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Label Content="Channel 2:" Grid.Row="3" Grid.Column="0" Height="Auto" Width="Auto" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Label Content="Channel 3:" Grid.Row="4" Grid.Column="0" Height="Auto" Width="Auto" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Label Content="Channel 4:" Grid.Row="5" Grid.Column="0" Height="Auto" Width="Auto" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</Border>
<Border Grid.Row="1" Grid.Column="1" BorderThickness="1" BorderBrush="Blue" >
<Grid Background="LightCyan">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="10" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="10" />
</Grid.RowDefinitions>
<Label Content="Module 2" Grid.Row="1" Grid.ColumnSpan="2" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="123.4" Grid.Row="2" Grid.Column="1" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="123.4" Grid.Row="3" Grid.Column="1" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="123.4" Grid.Row="4" Grid.Column="1" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="123.4" Grid.Row="5" Grid.Column="1" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="Channel 1:" Grid.Row="2" Grid.Column="0" Height="Auto" Width="Auto" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Label Content="Channel 2:" Grid.Row="3" Grid.Column="0" Height="Auto" Width="Auto" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Label Content="Channel 3:" Grid.Row="4" Grid.Column="0" Height="Auto" Width="Auto" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Label Content="Channel 4:" Grid.Row="5" Grid.Column="0" Height="Auto" Width="Auto" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</Border>
<Border Grid.Row="1" Grid.Column="2" BorderThickness="1" BorderBrush="Blue">
<Grid Background="LightCyan">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="10" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="10" />
</Grid.RowDefinitions>
<Label Content="Module 3" Grid.Row="1" Grid.ColumnSpan="2" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="123.4" Grid.Row="2" Grid.Column="1" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="123.4" Grid.Row="3" Grid.Column="1" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="123.4" Grid.Row="4" Grid.Column="1" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="123.4" Grid.Row="5" Grid.Column="1" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="Channel 1:" Grid.Row="2" Grid.Column="0" Height="Auto" Width="Auto" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Label Content="Channel 2:" Grid.Row="3" Grid.Column="0" Height="Auto" Width="Auto" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Label Content="Channel 3:" Grid.Row="4" Grid.Column="0" Height="Auto" Width="Auto" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Label Content="Channel 4:" Grid.Row="5" Grid.Column="0" Height="Auto" Width="Auto" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</Border>
<Border Grid.Row="1" Grid.Column="3" BorderThickness="1" BorderBrush="Blue">
<Grid Background="LightCyan">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="10" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="10" />
</Grid.RowDefinitions>
<Label Content="Module 4" Grid.Row="1" Grid.ColumnSpan="2" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="123.4" Grid.Row="2" Grid.Column="1" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="123.4" Grid.Row="3" Grid.Column="1" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="123.4" Grid.Row="4" Grid.Column="1" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="123.4" Grid.Row="5" Grid.Column="1" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="Channel 1:" Grid.Row="2" Grid.Column="0" Height="Auto" Width="Auto" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Label Content="Channel 2:" Grid.Row="3" Grid.Column="0" Height="Auto" Width="Auto" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Label Content="Channel 3:" Grid.Row="4" Grid.Column="0" Height="Auto" Width="Auto" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Label Content="Channel 4:" Grid.Row="5" Grid.Column="0" Height="Auto" Width="Auto" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</Border>
<Border Grid.Row="1" Grid.Column="4" BorderThickness="1" BorderBrush="Blue">
<Grid Background="LightCyan">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="10" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="10" />
</Grid.RowDefinitions>
<Label Content="Module 5" Grid.Row="1" Grid.ColumnSpan="2" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="123.4" Grid.Row="2" Grid.Column="1" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="123.4" Grid.Row="3" Grid.Column="1" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="123.4" Grid.Row="4" Grid.Column="1" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="123.4" Grid.Row="5" Grid.Column="1" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="Channel 1:" Grid.Row="2" Grid.Column="0" Height="Auto" Width="Auto" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Label Content="Channel 2:" Grid.Row="3" Grid.Column="0" Height="Auto" Width="Auto" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Label Content="Channel 3:" Grid.Row="4" Grid.Column="0" Height="Auto" Width="Auto" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Label Content="Channel 4:" Grid.Row="5" Grid.Column="0" Height="Auto" Width="Auto" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</Border>
<Border Grid.Row="1" Grid.Column="5" BorderThickness="1" BorderBrush="Blue">
<Grid Background="LightCyan">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="10" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="10" />
</Grid.RowDefinitions>
<Label Content="Module 6" Grid.Row="1" Grid.ColumnSpan="2" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="123.4" Grid.Row="2" Grid.Column="1" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="123.4" Grid.Row="3" Grid.Column="1" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="123.4" Grid.Row="4" Grid.Column="1" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="123.4" Grid.Row="5" Grid.Column="1" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="Channel 1:" Grid.Row="2" Grid.Column="0" Height="Auto" Width="Auto" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Label Content="Channel 2:" Grid.Row="3" Grid.Column="0" Height="Auto" Width="Auto" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Label Content="Channel 3:" Grid.Row="4" Grid.Column="0" Height="Auto" Width="Auto" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Label Content="Channel 4:" Grid.Row="5" Grid.Column="0" Height="Auto" Width="Auto" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</Border>
<StackPanel Margin="5,5,5,5" Grid.Row="3" Grid.ColumnSpan="4">
<WindowsFormsHost>
<dvc:Chart x:Name="chart" />
</WindowsFormsHost>
</StackPanel>
<StackPanel Grid.Row="0" Grid.ColumnSpan="6" Orientation="Horizontal">
<Label Content="IP-address:" Height="33" Width="Auto" FontSize="20" Padding="5,0,5,5"/>
<Label Content="192.168.1.10" Height="33" Width="Auto" FontSize="20" Padding="5,0,5,5"/>
</StackPanel>
<DataGrid x:Name="dgDataGrid" Grid.Row="4" Grid.Column="4" Grid.ColumnSpan="2" IsSynchronizedWithCurrentItem="False"/>
</Grid>
Code-behind:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Windows.Forms.DataVisualization.Charting;
using System.Drawing;
namespace WpfPromholComplementary_1
{
/// <summary>
/// Interaction logic for Window2.xaml
/// </summary>
public partial class Window2 : Window
{
public Window2()
{
InitializeComponent();
PLC plc1 = new PLC { ID = 1, Module_Number = "1", Channel_1 = "1234", Channel_2 = "5678", Channel_3 = "9012", Channel_4 = "3456" };
this.DataContext = plc1;
}
}
}
Upvotes: 2
Views: 210
Reputation: 4381
I have to decide to answer in 2 parts. One part will be clearly in Code-Behind approach, other will be in MVVM (Model-View-ViewModel).
Best idea to format the upper side of window is to use same component, where You will define source, instead of templating. Templating is useful at the places, where You have one control and You would like to change it's look (layout of controls).
At first You should create own UserControl
(I called it MyModuleFrame in example):
XML:
<UserControl x:Class="WpfPromholComplementary_1.MyModuleFrame"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfPromholComplementary_1"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
x:Name="mUserControl">
<Border BorderThickness="1" BorderBrush="Blue" CornerRadius="8,8,8,8">
<Grid Background="LightCyan">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="10" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="10" />
</Grid.RowDefinitions>
<Label Content="{Binding ItemSource.Number, ElementName=mUserControl}" Grid.Row="1" Grid.ColumnSpan="2" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="{Binding ItemSource.Ch1, ElementName=mUserControl}" Grid.Row="2" Grid.Column="1" FontSize="20" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Label Content="{Binding ItemSource.Ch2, ElementName=mUserControl}" Grid.Row="3" Grid.Column="1" FontSize="20" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Label Content="{Binding ItemSource.Ch3, ElementName=mUserControl}" Grid.Row="4" Grid.Column="1" FontSize="20" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Label Content="{Binding ItemSource.Ch4, ElementName=mUserControl}" Grid.Row="5" Grid.Column="1" FontSize="20" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Label Content="Channel 1:" Grid.Row="2" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Label Content="Channel 2:" Grid.Row="3" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Label Content="Channel 3:" Grid.Row="4" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Label Content="Channel 4:" Grid.Row="5" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</Border>
</UserControl>
C#:
namespace WpfPromholComplementary_1
{
/// <summary>
/// Interaction logic for MyModuleFrame.xaml
/// </summary>
public partial class MyModuleFrame : UserControl
{
public MyModuleFrame()
{
InitializeComponent();
}
public Module ItemSource
{
get { return (Module)GetValue(ItemSourceProperty); }
set { SetValue(ItemSourceProperty, value); }
}
// Using a DependencyProperty as the backing store for ItemsSource. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ItemSourceProperty =
DependencyProperty.Register("ItemSource", typeof(Module), typeof(MyModuleFrame), new PropertyMetadata(default(Module)));
}
}
It is really imporant to define set the properties of all UserControls as DependencyProperty. Why? Because WPF is using them to do everything related to View handling. On the initialization, they are registered in the WPF framework & once somebody want to access them/they will call WPF (who returns the value), instead of direct approach.
Once You've defined the control, You can use it on the window. I have removed some code from start (I dont have references) & the end code just so You have an idea:
<Window x:Class="WpfPromholComplementary_1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:loc = "clr-namespace:WpfPromholComplementary_1"
xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
Title="Window2" Height="800" Width="1000">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition Height="210" />
<RowDefinition Height="30" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<loc:MyModuleFrame Grid.Row="1" Grid.Column="0" ItemSource="{Binding Module1}"/>
<loc:MyModuleFrame Grid.Row="1" Grid.Column="1" ItemSource="{Binding Module2}"/>
<loc:MyModuleFrame Grid.Row="1" Grid.Column="2" ItemSource="{Binding Module3}"/>
<loc:MyModuleFrame Grid.Row="1" Grid.Column="3" ItemSource="{Binding Module4}"/>
<!-- other modules & stuff-->
</Grid>
</Window>
And once You get to the point above, You need to get the dynamical data, that can be obtained 3 ways:
this
)Based on the choosen option, You have to update code above.
Also we should have defined Model for our App - Module class. This code below does not support View update. For support You must implement INotifyPropertyChanged interface (more below):
//Simplified
public class Module
{
public string Number { get; set; }
public double Ch1 { get; set; }
public double Ch2 { get; set; }
public double Ch3 { get; set; }
public double Ch4 { get; set; }
}
ViewModel:
public class MainViewModel
{
public Module Module1 { get; set; } = new Module()
{
Number = "1",
Ch1 = 123.4,
Ch2 = 123.4,
Ch3 = 123.4,
Ch4 = 123.4
};
/* other modules... */
}
MVVM approach:
App.config:
<Application x:Class="WpfPromholComplementary_1.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfPromholComplementary_1"
StartupUri="MainWindow.xaml">
<Application.Resources>
<local:MainViewModel x:Key="MainViewModel"/>
</Application.Resources>
</Application>
Code-behind approach:
View.cs:
public partial class Window
{
public Window()
{
InitializeComponent();
this.DataContext = this;
}
public Module Module1 { get; set; } = new Module(); //in this case You do not need ViewModel
}
At this point You should have working application, where You cannot change anything.
Now there are 2 ways to update the values in View, one is following the proper manner of the MVVM, other is in again in code-behind. I will describe both just for reference:
At first Your Modul needs to inherit from INotifyPropertyChange (example just for 2 propertie):
using System.ComponentModel;
public class Module : INotifyPropertyChanged
{
private string _number;
public string Number
{
get { return this._number; }
set
{
if (_number == value) return;
_number = value;
OnPropertyChanged(nameof(Number));
}
}
private double _ch1;
public double Ch1
{
get { return this._ch1; }
set
{
if (_ch1 == value) return;
_ch1 = value;
OnPropertyChanged(nameof(Ch1));
}
}
//other channels fits there
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string aNameOfProperty)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(aNameOfProperty));
}
}
Code-behind:
Now let's say we want to handle an event to the button click (XML):
<Button Click="MyButton_Click"/>
In code-behind, we can do (C#):
private void MyButton_Click(object sender, MouseEventArgs e)
{
//Your ViewModel is stored in DataContext, You can just cast to approach properties
var VM = (this.DataContext as MainViewModel);
VM.Module1.Number = "Module Number Xyz";
}
MVVM: MVVM approach is a bit harder as You need to implement ICommand interface on some command class see relay command for reference.
Once You've got this, XML:
<Button Command="{Binding DoSomeWorkCmd}"/>
In Your ViewModel:
private ICommand _DoSomeWorkCmd;
public ICommand DoSomeWorkCmd
{
get
{
if (_DoSomeWorkCmd != null) return _DoSomeWorkCmd;
_DoSomeWorkCmd = new RelayCommand((object aParam)=> { return true; }, (object aParam) =>
{
this.Module1.Number = "MyNewNumber XyZ";
});
return this._DoSomeWorkCmd;
}
}
MVVM example of whole solution can be downloaded on my GIT: https://github.com/Tatranskymedved/WpfPromholComplementary_1
Upvotes: 2