0

I've recently moved from WinForms to WPF and I'm finding it hard to separate ViewModel and View. I'm designing the entire view in the ViewModel. Eventhough it works, I'm sure it is not the right way.

Is there anyway I can separate View and ViewModel without modifying much? I've did some research on it, but it wasn't that helpful.

EDIT

XAML

<Window x:Class="PackageDeliveryTool.FolderCheck"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Main Window" Height="350" Width="640" ResizeMode="NoResize" ShowInTaskbar="False" Topmost="True" Cursor="Arrow" Closing="Window_Closing">
<!-- From here is the XAML view code which includes button/Grid/StackPanel etc -->
    </Window>

And I have separate CS file for model. which has properties and propertyChanged Events.

This is XAML.Cs file of particular Window. has actions and and Model Object(s),

public partial class CopyMessageWindow : Window
{
    Model m = new Model("someValue");
    public CopyMessageWindow()
    {
        InitializeComponent();
    }


    public void StartButton_Click(object sender, RoutedEventArgs e){
        //Some code goes here uses Model instance
    }

public void OtherLogicMethod(int val){
    //Some other logic not related to UI, but to Background program. Also uses Model Instance
    }

    private void CancelButton_Click(object sender, RoutedEventArgs e)
    {
        //When cancel button is clicked, uses Model instance
    }
}

EDITx2

I've already written much code. I need a more simplistic way of separating view and ViewModel.

Prajwal
  • 3,930
  • 5
  • 24
  • 50
  • Hard to say without knowing what you've done so far. – Abion47 Oct 03 '16 at 06:29
  • A very basic way to look at it is that the "Designing" part is in the View, while the "Loading" data or such coding is done in the ViewModel. For a good beginner-friendly tutorial, try [MVVM Tutorial](https://www.tutorialspoint.com/mvvm/index.htm) – Keyur PATEL Oct 03 '16 at 06:29
  • ViewModel glues your Model and View together. It can contain the logic to update the view (i.e. background color). If the view update can be done through XAML then don't place it on your ViewModel. – jegtugado Oct 03 '16 at 06:32
  • 1
    It's better to show the code you already wrote (may be, some excerpts). – Dennis Oct 03 '16 at 06:33
  • Where is your ViewModel? If you follow a proper MVVM pattern then you can achieve 0% code-behind in most cases. – jegtugado Oct 03 '16 at 07:10
  • "I've did some research on it, but it wasn't that helpful" I don't believe you. There is way too many good resources for this to be true. – Euphoric Oct 03 '16 at 07:53

1 Answers1

2

Follow these steps:

1.Create your model:

 public class Model
 {
    public string  Name { get; set; }
 }

2. Create your ViewModel, it will be your view DataContext:

public class MainViewModel : BindableBase
  {      
    public MainViewModel()
    {
        _model = new Model {Name = "Test"};
    }
    private Model _model;
    public Model Model
    {
        get
        {
            return _model;
        }
        set
        {
            _model = value;
            OnPropertyChanged("Model");       
        }
    }
}

3.In order to implement the MVVM pattern for full separation leave your view.cs empty:

 public partial class MainWindow : Window
   {
    public MainWindow()
    {
        InitializeComponent();
    }
   }

4. Create yout view and set the DataContext to your ViewModel:

    <Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    DataContext="{StaticResource MainViewModel}"><Grid><TextBlock Text="{Binding Model.Name, Mode=TwoWay}"/></Grid></Window>

5. Implement your BindableBase:

public class BindableBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged = delegate { };

    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = this.PropertyChanged;
        if (handler != null)
        {
            var e = new PropertyChangedEventArgs(propertyName);
            handler(this, e);
        }
    }
}
Rom
  • 1,183
  • 1
  • 8
  • 18
  • What about calling methods? and where should I keep program logic? – Prajwal Oct 03 '16 at 07:13
  • You need to use commands in your view model: http://stackoverflow.com/a/1468830/3955716 – Rom Oct 03 '16 at 07:15
  • A reasonable tutorial but do note that Model.Name does not implement INotifyPropertyChanged. Could be a reason to duplicate that property. – H H Oct 03 '16 at 07:17
  • 1
    @Prajwal - take a look at the business layer in [the picture here](http://stackoverflow.com/a/32224997/60761) – H H Oct 03 '16 at 07:21