The WPF framework can be used with the MVVM (https://en.wikipedia.org/wiki/Model–view–viewmodel) pattern. Glue provides a useful ViewModel class which can be used as the base class for view models in plugins. This tutorial will show you how to use the MVVM pattern to display data.
Creating a ViewModel
Developers familiar with MVVM can implement view models according to their own preferred patterns or frameworks, but we will be covering one way to implement view models using Glue's base ViewModel class. Specifically we will be modifying the plugin from the previous tutorial to display information about the selected file. First, we'll create a view model for the control:
Right-click on the plugin project and select Add -> New Folder
Name the folder ViewModels
Right-click on the newly-created folder and select Add -> Class
Enter the name MainControlViewModel
Click Add
Next we'll modify the view model to implement the base ViewModel class and to have properties for displaying information about the file. Modify MainControlViewModel.cs as shown in the following code snippet:
using FlatRedBall.Glue.MVVM;
namespace TutorialPlugin.ViewModels
{
class MainControlViewModel : ViewModel
{
public string FileNameDisplay
{
get => Get<string>();
set => Set(value);
}
public string WriteTimeDisplay
{
get => Get<string>();
set => Set(value);
}
}
}
The code above can be used to display the file name and write time of the selected file in our MainControl. Next, we'll update the XAML to add TextBlocks with binding, as shown in the following XAML:
Finally we can create add a MainControlViewModel instance to our MainTutorialPlugin class and assign the view model in the HandleItemSelected method, as shown in the following code snippet:
using FlatRedBall.Glue.Plugins;
using FlatRedBall.Glue.Plugins.ExportedImplementations;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TutorialPlugin
{
[System.ComponentModel.Composition.Export(typeof(FlatRedBall.Glue.Plugins.PluginBase))]
public class MainTutorialPlugin : FlatRedBall.Glue.Plugins.PluginBase
{
Controls.MainControl mainControl;
PluginTab tab;
public override string FriendlyName => "Tutorial Plugin";
ViewModels.MainControlViewModel viewModel;
public override void StartUp()
{
this.ReactToItemSelectHandler += HandleItemSelected;
}
private void HandleItemSelected(TreeNode selectedTreeNode)
{
var currentFile = GlueState.Self.CurrentReferencedFileSave;
if(currentFile == null)
{
tab?.Hide();
}
else
{
if(tab == null)
{
mainControl = new Controls.MainControl();
viewModel = new ViewModels.MainControlViewModel();
mainControl.DataContext = viewModel;
tab = this.CreateTab(mainControl, "Tutorial Plugin");
}
tab.Show();
var fullFileName = GlueCommands.Self.ProjectCommands.MakeAbsolute(
currentFile.Name, forceAsContent: true);
UpdateToFullFile(fullFileName);
}
}
private void UpdateToFullFile(string fullFileName)
{
viewModel.FileNameDisplay = $"File Name: {fullFileName}";
var writeTime = System.IO.File.GetLastWriteTime(fullFileName);
viewModel.WriteTimeDisplay = $"Last write time: {writeTime}";
}
}
}
Now we can run our project and see information about the selected file.
Reacting to File Changes
Glue can notify plugins when a file changes. To respond to these changes, the plugin can use the ReactToFileChangeHandler delegate, as shown in the following code snippet: