• 动态加载Silverlight应用的dll文件(可实现插件功能)


      在Mike Taulty的视频教程中有一个动态加载silverlight应用程序的DEMO,其程序运行效果如下:

         当加载dll之后:

      
     
      其实实现这个的效果本身并不难,主要是这个DEMO的应用场景可以让人做很大的扩展,比如说插
    件机制等.

      好了,让我们看看如何实际去开发这个示例,以便让大家从流程和技术点上有个了解.
      首先我们需要建立一个叫DynamicLoading的silverlight Application, 然后将如下的内容拷贝
    到Page.xaml中:

    <UserControl x:Class="DynamicLoading.Page"
        xmlns
    ="http://schemas.microsoft.com/client/2007" 
        xmlns:x
    ="http://schemas.microsoft.com/winfx/2006/xaml" 
        Width
    ="400" Height="300">
        
    <Grid x:Name="LayoutRoot" Background="White">
           
    <Grid.RowDefinitions >
                
    <RowDefinition />
                
    <RowDefinition />
            
    </Grid.RowDefinitions>
            
           
    <StackPanel>
              
    <StackPanel>    
                    
    <TextBox Width="200" x:Name="txtPlugIn" Margin="10" Text="Implementation.dll" />
              
    </StackPanel>
                
    <Button HorizontalAlignment="Center" Margin="10" Width="96" Content="加载DLL" 
       Click
    ="OnClick" />
            
    </StackPanel>

                
    <Grid  Grid.Row="1" Background="AliceBlue" Margin="20" x:Name="gridHosting">
                
                
    </Grid>
            
    <StackPanel  VerticalAlignment="Bottom">
                
    <TextBlock x:Name="txtToEdit" FontSize="16" FontStyle="italic"  Text="编辑内容" 
      TextAlignment
    ="center" HorizontalAlignment="Stretch" Grid.Row="2" 
      VerticalAlignment
    ="Center"/>
            
    </StackPanel>
        
    </Grid>
    </UserControl>

         然后我们需要先建立一个接口文件(类似于插件接口),所以在当前SLN下新加一个Silverlight Class
    Library 项目,名称为:Interfaces
     .将class.cs文件改名为:IEditText.cs .
    将如下接口内容拷贝到该cs文件中:
      

    public class TextChangedEventArgs : EventArgs
        {
            
    public string Text { getset; }
        }

        
    public interface IEditText
        {
            UIElement GetControls();
            
    void SetText(string text);
            
    event EventHandler<TextChangedEventArgs> TextChanged;
        }

      编译这个接口项目.接下来我们将会实现这个接口(相当于实际的插件功能).
    我们再新建一个叫Implementation的Silverlight Class Library 项目,重命名class.cs文件为Editor.cs
    , 将如下内容拷贝到项目的cs文件中:
     

    public class Editor : Interfaces.IEditText
    {
        TextBox textBox;

        
    public Editor()
        {
            textBox 
    = new TextBox();
        }

        
    //插件运行时加载的控件(界面)
        public UIElement GetControls()
        {
            StackPanel Panel 
    = new StackPanel();

            StackPanel stackPanel 
    = new StackPanel();
            stackPanel.Margin 
    = new Thickness(5);
            stackPanel.Orientation 
    = Orientation.Horizontal;

            textBox 
    = new TextBox();
            textBox.Width 
    = 300;
            textBox.Height 
    = 70;
            Button button 
    = new Button();
            button.Content 
    = "点击这里";
            button.Click 
    += OnButtonClick;
            button.Width 
    = 60;

            stackPanel.Children.Add(textBox);
            Panel.Children.Add(stackPanel);
            Panel.Children.Add(button);

            
    return Panel;
        }

        
    public void SetText(string text)
        {
            textBox.Text 
    = text;
        }

        
    //将点击提交按钮时,更新相应的界面内容
        void OnButtonClick(object sender, EventArgs args)
        {
            
    if (TextChanged != null)
            {
                TextChanged(
    thisnew Interfaces.TextChangedEventArgs()
                {
                    Text 
    = textBox.Text
                });
            }
        }
        
    public event EventHandler<Interfaces.TextChangedEventArgs> TextChanged;
    }

      之后,我们编译一下译项目.

      下面看一下加载上面类库的代码(位于Page.xaml.cs文件中):   

    public partial class Page : UserControl
    {
        
    public Page()
        {
            InitializeComponent();
        }

    //点击加载按钮事件
        void OnClick(object sender, EventArgs args)
        {
            
    //获取要加载的dll文件信息
            string assembly = txtPlugIn.Text;
            WebClient client 
    = new WebClient();
            
    //准备获取dll文件的信息
            client.OpenReadCompleted += OnReadCompleted;
            client.OpenReadAsync(
    new Uri(assembly, UriKind.Relative));
        }

        
    void OnReadCompleted(object sender, OpenReadCompletedEventArgs e)
        {
            AssemblyPart part 
    = new AssemblyPart();
            
    //获取加载的dll信息(stream格式)
            Assembly assembly = part.Load(e.Result);
    //构造该对象(插件)的实例
            IEditText editor =
                 assembly.CreateInstance(
    "Implementation.Editor"as IEditText;

            
    if (editor != null)
            {  
    //加载其中的控件(gridHosting类型为<Grid>)
                gridHosting.Children.Add(editor.GetControls());
                editor.SetText(txtToEdit.Text);
                
    //完成事件绑定
                editor.TextChanged += OnTextChanged;
            }
        }
        
        
    //内容更新
        void OnTextChanged(object sender, Interfaces.TextChangedEventArgs e)
        {
            txtToEdit.Text 
    = e.Text;
        }
    }

        当然要编译还要引用一下前面写的接口项目(Interfaces),这样代码部分就完成了.这里我们还
    要将类库Implementation.dll(插件)放入web项目中的ClientBin文件夹下.这样我们就可以运行文章
    开始处的页面了.

      是不是很简单,这里面主要的一块内容就是使用WebClient读取dll文件,如下:

    WebClient client = new WebClient();
    client.OpenReadCompleted 
    += OnReadCompleted;
    client.OpenReadAsync(
    new Uri(assembly, UriKind.Relative));


         其它的内容都是小Case:)

        好了,今天的内容就到这里了,感兴趣的朋友可以一起来讨论:)

        源码下载请 点击这里:)

  • 相关阅读:
    实现系统托盘
    MDI窗体应用
    C#窗体的常用设置
    什么是UWP应用
    关于用js写缓动 动画
    关于tab栏切换的解析
    函数
    for循环
    if语句
    js
  • 原文地址:https://www.cnblogs.com/daizhj/p/1210894.html
Copyright © 2020-2023  润新知