C# 将一个或另一个WPF DLL加载到主WPF应用程序中
正在查看加载XAML/events/everything,该DLL连接到用户控件,该DLL在运行时根据配置文件加载到另一个WPF项目中 所以你有两个DLL,只有一个是基于JSON配置加载的,但是我希望我的所有按钮和所有东西都能正常工作。这是我的密码 灰色动态链接库的用户控制C# 将一个或另一个WPF DLL加载到主WPF应用程序中,c#,wpf,xaml,dll,C#,Wpf,Xaml,Dll,正在查看加载XAML/events/everything,该DLL连接到用户控件,该DLL在运行时根据配置文件加载到另一个WPF项目中 所以你有两个DLL,只有一个是基于JSON配置加载的,但是我希望我的所有按钮和所有东西都能正常工作。这是我的密码 灰色动态链接库的用户控制 <UserControl x:Class="WPFGreyButtonTest.InstrumentUserControl" xmlns="http://schemas.microsoft.c
<UserControl x:Class="WPFGreyButtonTest.InstrumentUserControl"
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"
xmlns:local="clr-namespace:WPFGreyButtonTest"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<Label x:Name="colourName" Content="GREY" HorizontalAlignment="Left" Height="93" Margin="284,88,0,0" VerticalAlignment="Top" Width="243" FontWeight="Bold" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" FontSize="50" Foreground="#FF8B8B8B"/>
</Grid>
</UserControl>
没有实际代码
紫色DLL的用户控件
<UserControl x:Class="WPFPurpleButtonTest.InstrumentUserControl"
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"
xmlns:local="clr-namespace:WPFPurpleButtonTest"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<Label x:Name="colourName" Content="PURPLE" HorizontalAlignment="Left" Height="93" Margin="284,88,0,0" VerticalAlignment="Top" Width="243" FontWeight="Bold" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" FontSize="50" Foreground="#FFDC00FF"/>
<Button x:Name="button" Content="Button" HorizontalAlignment="Left" Margin="365,253,0,0" VerticalAlignment="Top" Width="75"/>
</Grid>
</UserControl>
代码(两个DLL具有相同的类名,即InstrumentUserControl)
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
使用System.Windows;
使用System.Windows.Controls;
使用System.Windows.Data;
使用System.Windows.Documents;
使用System.Windows.Input;
使用System.Windows.Media;
使用System.Windows.Media.Imaging;
使用System.Windows.Navigation;
使用System.Windows.Shapes;
命名空间WPFPurpleButtonTest
{
///
///InstrumentUserControl.xaml的交互逻辑
///
公共部分类InstrumentUserControl:UserControl
{
公共静态只读DependencyProperty InnerButtonProperty=DependencyProperty.Register(“InnerButton”、typeof(Button)、typeof(InstrumentUserControl));
公共按钮内部按钮
{
获取{return(Button)GetValue(InnerButtonProperty);}
set{SetValue(InnerButtonProperty,value);}
}
公共工具用户控制()
{
初始化组件();
InnerButton=按钮;
}
}
}
主WPF应用程序代码
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WPFSandBox
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
UserControl userControl = null;
InstrumentEnum instrumentType = InstrumentEnum.Invalid;
string dllToLoad = null;
// When we first initialize our WPF app, in the constructor we can
// allow a config file (such as a json) to be read and load up
// an appropriate user control view
public MainWindow()
{
InitializeComponent();
ReadJson();
LoadRunTimeDLL();
//var ucs = new List<InstrumentUserControl>();
var ucs = new List<UserControl>();
ucs.Add(userControl);
//ucs.Add(new UserControl1());
//ucs.Add(new UserControl1());
//ucs.Add(new UserControl1());
ic.ItemsSource = ucs;
}
private void ReadJson()
{
using (StreamReader r = new StreamReader("../../Config/Config.json"))
{
string json = r.ReadToEnd();
var jsonData = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
foreach (var entry in jsonData)
{
if (entry.Key == "InstrumentType")
{
Enum.TryParse(entry.Value, out instrumentType);
}
else if (entry.Key == "DllToLoad")
{
dllToLoad = entry.Value;
}
}
}
}
private void LoadRunTimeDLL()
{
string assemblyName = string.Format("{0}\\{1}.dll",
new FileInfo(Assembly.GetExecutingAssembly().Location).DirectoryName, dllToLoad);
if (assemblyName != null)
{
Assembly asm = Assembly.LoadFile(assemblyName);
Type[] tlist = asm.GetTypes();
foreach (Type t in tlist)
{
if (t.Name == "InstrumentUserControl")
{
userControl = Activator.CreateInstance(t) as UserControl;
break;
}
}
if (userControl != null)
{
//contentControl.Content = userControl;
}
}
}
}
}
使用Newtonsoft.Json;
使用Newtonsoft.Json.Linq;
使用制度;
使用System.Collections.Generic;
使用System.IO;
使用System.Linq;
运用系统反思;
使用系统文本;
使用System.Threading.Tasks;
使用System.Windows;
使用System.Windows.Controls;
使用System.Windows.Data;
使用System.Windows.Documents;
使用System.Windows.Input;
使用System.Windows.Media;
使用System.Windows.Media.Imaging;
使用System.Windows.Navigation;
使用System.Windows.Shapes;
命名空间WPFSandBox
{
///
///MainWindow.xaml的交互逻辑
///
公共部分类主窗口:窗口
{
UserControl UserControl=null;
InstrumentEnum instrumentType=InstrumentEnum.无效;
字符串dllToLoad=null;
//当我们第一次初始化WPF应用程序时,在构造函数中我们可以
//允许读取和加载配置文件(如json)
//适当的用户控件视图
公共主窗口()
{
初始化组件();
ReadJson();
LoadRunTimeDLL();
//var ucs=新列表();
var ucs=新列表();
添加(用户控制);
//添加(新的UserControl1());
//添加(新的UserControl1());
//添加(新的UserControl1());
ic.ItemsSource=ucs;
}
私有void ReadJson()
{
使用(StreamReader r=newstreamreader(“../../Config/Config.json”))
{
字符串json=r.ReadToEnd();
var jsonData=JsonConvert.DeserializeObject(json);
foreach(jsonData中的var条目)
{
如果(entry.Key==“InstrumentType”)
{
Enum.TryParse(entry.Value,out instrumentType);
}
else if(entry.Key==“dlltoad”)
{
dllToLoad=输入值;
}
}
}
}
私有void LoadRunTimeDLL()
{
string assemblyName=string.Format(“{0}\\{1}.dll”,
新文件信息(Assembly.getExecutionGassembly().Location).DirectoryName,dllToLoad);
if(assemblyName!=null)
{
Assembly asm=Assembly.LoadFile(assemblyName);
类型[]tlist=asm.GetTypes();
foreach(t列表中的类型t)
{
if(t.Name==“InstrumentUserControl”)
{
userControl=Activator.CreateInstance(t)作为userControl;
打破
}
}
if(userControl!=null)
{
//contentControl.Content=userControl;
}
}
}
}
}
这是主窗口xaml
<Window x:Class="WPFSandBox.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"
xmlns:local="clr-namespace:WPFSandBox"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<!--<Grid>
<ContentControl Grid.Row="1" x:Name="contentControl" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch"/>
</Grid>-->
<ItemsControl x:Name="ic" />
</Window>
任何帮助将不胜感激,我如何才能确保无论哪个DLL得到加载,按钮工作正常
我正在尝试在运行时加载WPF DLL。工作正常,但按钮和事件绑定到主WPF应用程序是我不知道如何做的好的,假设您当前有此设置:
Solution: MainApp
- Project: MainApp (WPF App)
- Project: PurpleButton (Class Library)
- Project: GreyButton (Class Library)
我所说的是添加另一个项目,如下所示:
Solution: MainApp
- Project: MainApp (WPF App)
- Project: MainAppPlugins (Class Library) <-----
- Project: WPFPurpleButtonTest (Class Library)
- Project: WPFGreyButtonTest (Class Library)
using System;
using System.Windows.Controls;
namespace MainAppPlugins
{
public abstract class PluginButton : UserControl
{
public event EventHandler OnProcessedSomeData;
}
}
然后更新所有其他项目(MainApp、WPFPurpleButtonTest和WPFGreyButtonTest),并向MainAppPlugins添加项目引用(以便每个项目都知道什么是“MainAppPlugins.PluginButton”)
在紫色和灰色中,将用户控件更改为从MainAppPlugins.PluginButton扩展,而不是从UserControl扩展。所以你在两个地方做这个。首先,在代码隐藏中(在.cs文件中):
…在创建控件时,您还可以使用更具体的通用插件按钮类型:
// userControl = Activator.CreateInstance(t) as UserControl;
userControl = Activator.CreateInstance(t) as MainAppPlugins.PluginButton;
…这意味着MainApp代码现在可以引用所有常见事件/代码,例如我们的自定义OnProcessedSomeData事件:
userControl.OnProcessedSomeData+=…此处是您的事件处理程序
因此,灰色和紫色按钮可能有90%不同的代码,但其他10%由事件、属性等定义在PluginButton中可以找到任何代码、事件和属性。因为MainApp知道
namespace WPFGreyButtonTest
{
public partial class InstrumentUserControl : PluginButton // <--
{
...your existing code...
}
}
<mainappplugins:PluginButton x:Class="WPFGreyButtonTest.InstrumentUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:mainappplugins="clr-namespace:MainAppPlugins;assembly=MainAppPlugins"
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"
xmlns:local="clr-namespace:WPFGreyButtonTest"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
...
</mainappplugins:PluginButton>
// if (t.Name == "InstrumentUserControl")
if(t.BaseType == typeof(MainAppPlugins.PluginButton))
{
...
}
// userControl = Activator.CreateInstance(t) as UserControl;
userControl = Activator.CreateInstance(t) as MainAppPlugins.PluginButton;
public abstract class PluginButton : UserControl
{
...
public virtual string GetData()
{
return "Default value";
}
}
namespace WPFGreyButtonTest
{
public partial class InstrumentUserControl : PluginButton
{
...your existing code...
public override string GetData()
{
return "Data from the Grey button";
}
}
}
namespace WPFPurpleButtonTest
{
public partial class InstrumentUserControl : PluginButton
{
...your existing code...
public override string GetData()
{
return "Data from the Purple button";
}
}
}