[Songqw.Net 基础]WPF实现简单的插件化开发

原文: [Songqw.Net 基础]WPF实现简单的插件化开发

版权声明:本文为博主原创文章,未经博主允许可以随意转载 https://blog.csdn.net/songqingwei1988/article/details/50895733

接着上一篇博客, 那里实现了简单的控制台加载插件,在这里通过WPF实现,做个备份.


WPF控件空间经常会与WinFrom混淆,要记得WPF控件是引用 using System.Windows.Controls;


1.构建控件:

WpfPart1.xaml

<UserControl x:Class="Songqw.Net.Plugins.Test.WPFPlugins.WpfPart1"
             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" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
        <Grid.Background>
            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                <GradientStop Color="#FF7C44F5" Offset="0"/>
                <GradientStop Color="White" Offset="1"/>
            </LinearGradientBrush>
        </Grid.Background>

    </Grid>
</UserControl>
 

WpfPart1.xaml.cs

using System;
using System.Windows.Controls;
using Songqw.Net.Plugins.Interface;

namespace Songqw.Net.Plugins.Test.WPFPlugins
{
    /// <summary>
    /// WpfPart1.xaml 的交互逻辑
    /// </summary>
    public partial class WpfPart1 : UserControl, IPluginMember
    {
        public WpfPart1()
        {
            InitializeComponent();
        }

        public string PluginName()
        {
            return "WpfPart1";
        }

        public int PluginId()
        {
            return GetHashCode();
        }

        public object InitPlugin()
        {
            return this;
        }

        public object InitPlugin(object[] paras)
        {
            return this;
        }

        public bool DisposePlugin()
        {
            throw new NotImplementedException();
        }
    }
}

WpfPart2 同上, 修改下名称即可.


测试WPF程序:

MainWindow.xaml

<Window x:Class="Songqw.Net.Plugins.Test.WpfApplication.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="WPF插件测试程序" Height="350" Width="525">
    <Grid>
        
        <Grid.RowDefinitions>
            <RowDefinition Height="20"/>
            <RowDefinition Height="100*"/>
            <RowDefinition Height="30"/>
        </Grid.RowDefinitions>
        
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="120"/>
            <ColumnDefinition Width="100*"/>
        </Grid.ColumnDefinitions>
        
        <StackPanel x:Name="PartPanel" Margin="0,4,0,2" Grid.Row="1"/>
        
        <Grid x:Name="PartGrid" 
              HorizontalAlignment="Left" Height="320" VerticalAlignment="Top" Width="397"
              Grid.Column="1" 
              Grid.Row="0" 
              Grid.RowSpan="3" Background="#FF686868"/>

        <Label  Content="加载插件数量 : 0 "
                Name="NumLabel"
                Grid.Row="0"
                Grid.Column="0" 
                VerticalAlignment="Top" Height="20" Padding="5,0" Margin="5,0"/>
        
        <Button Content="选择目录"
                Grid.Row="2" 
                Grid.Column="0"  
                HorizontalAlignment="Left"   VerticalAlignment="Top" 
                Margin="21,3,0,0"   Width="75" Click="Button_Click" 
               />

    </Grid>
</Window>

MainWindow.xaml.cs:

using System;
using System.Windows;
using System.Windows.Forms;
using Songqw.Net.Plugins.Interface;
using Songqw.Net.Plugins.Tool;
using Application = System.Windows.Forms.Application;
using Button = System.Windows.Controls.Button;

namespace Songqw.Net.Plugins.Test.WpfApplication
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            var folderBrowserDialog = new FolderBrowserDialog();

            folderBrowserDialog.SelectedPath = Application.StartupPath;

            folderBrowserDialog.ShowDialog();

            if (!string.IsNullOrEmpty(folderBrowserDialog.SelectedPath))
            {
                PartGrid.Children.Clear();
                PartPanel.Children.Clear();

                var plugins = LoadLibrary.LoadDocument(Application.StartupPath);

                if (plugins != null && plugins.Length > 0)
                {
                    foreach (Type t in plugins)
                    {
                        var instance = LoadLibrary.InitClassByType(t) as IPluginMember;

                        if (instance == null)
                            continue;

                        var btn = new System.Windows.Controls.Button
                        {
                            Tag = instance,
                            Content = instance.PluginName(),
                            Height = 25
                        };

                        btn.Click += btn_Click;
                        PartPanel.Children.Add(btn);
                    }
                    NumLabel.Content = string.Format("加载插件数量 : {0}", plugins.Length);
                }
            }
        }

        void btn_Click(object sender, RoutedEventArgs e)
        {
            PartGrid.Children.Clear();
            var btn = sender as Button;
            var instance = btn.Tag as IPluginMember;
            var ui = instance.InitPlugin();
            var uiElement = ui as UIElement;
            PartGrid.Children.Add(uiElement);
        }
    }
}


测试效果:



实际使用时, 可以通过InitPlugin 方法传递参数, 进行赋值等操作.   资源释放方面需要额外注意....

猜你喜欢

转载自www.cnblogs.com/lonelyxmas/p/9824851.html