Vielleicht für Anfänger interessant, die eine Plugin-Engine für eine WPF-Anwendung bauen wollen und Inhalte dynamisch hinzufügen wollen:
MVVM siehe: [Artikel] MVVM und DataBinding
Das ganze ist natürlich stark vereinfacht und nutzt direkt das MainViewModel, was für aufwendigere Anwendungen wahrscheinlich ungeeignet ist.
Was sollen unsere Plugins wissen?
public interface IHostView
{
public string WindowTitle { get; set; }
}
Z.B. MainViewModel implementiert IHostView:
public class MainViewModel : BaseViewModel, IHostView
{
private List<Plugin> _Plugins = new List<Plugin>() ;
private string _WindowTitle = "Meine Hauptanwendung";
public string WindowTitle {
get => _WindowTitle;
set {
_WindowTitle = value;
OnPropertyChanged(nameof(WindowTitle));
}
}
public List<MenuItem> PluginMenuItems
{
get
{
var list = new List<MenuItem>();
foreach (var plugin in _Plugins)
list.Add(plugin.GetPluginMenuItem());
return list;
}
}
public MainViewModel()
{
// Plugins dynamisch hinzufuegen
_Plugins.Add(new MeinPlugin(this));
}
}
Abstrakte Plugin-Klasse, was soll es können:
public abstract class Plugin
{
public IHostView _Host;
public Plugin(IHostView host)
{
_Host = host;
}
public abstract string Name { get; }
// Standardmaessig kein MenuItem
public virtual MenuItem GetPluginMenuItem() { return null; }
}
Plugin-Implementierung:
public class MeinPlugin : Plugin
{
public MeinPlugin(IHostView host) : base(host)
{
}
public override string Name => "Mein Plugin";
public override MenuItem GetPluginMenuItem()
{
var menuItem = new MenuItem();
// Alternativ Command
menuItem.Header = this.Name;
menuItem.Click += MenuItem_Click;
return menuItem;
}
private void MenuItem_Click(object sender, System.Windows.RoutedEventArgs e)
{
_Host.WindowTitle = "Hallo !";
}
Plugin Obermenü im Window:
...
Title="{Binding WindowTitle}" Height="450" Width="800">
<Window.DataContext>
<vms:MainViewModel />
</Window.DataContext>
<Menu DockPanel.Dock="Top">
<MenuItem Header="File">
<MenuItem Header="Exit"/>
</MenuItem>
<MenuItem Header="Plugins" ItemsSource="{Binding PluginMenuItems}"/>
</Menu>
Mittels ItemsControl könnte man auch Controls in verschiedenen Bereichen dynamisch hinzufügen, etc.