Click here to Skip to main content
15,867,771 members
Please Sign up or sign in to vote.
4.00/5 (2 votes)
See more:
Hi sir

Ok, I want loading any UserContols as DLL on a MainWindow project as host by selecting them in runtime.
I tried this article SelfContainedAssembly[^] and I converted it to a WPF project that you can see MyProject[^], also test it with StackPanel and etc succesfully, but I want develope a WPF UserControl project like this
HTML
<usercontrol x:class="ManyWpfControlLibrary.UserControl1" xmlns:x="#unknown">
             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="150" d:DesignWidth="300">
    <grid removed="#FFFA8383">

    </grid>
</usercontrol>


with code-behind
C#
namespace ManyWpfControlLibrary
{
    /// <summary>
    /// Interaction logic for UserControl1.xaml
    /// </summary>
    public partial class UserControl1 : UserControl
    {
        public UserControl1()
        {
            InitializeComponent();
        }
    }
}


This UserControl compiled to a DLL file, finally it would insert into my MainWindow project at runtime, but I couldn't to do this.

In fact, we haven't aware about the DLL (UserControl compiled), it created and developed offline by another persons and there is on a different assembly, only we load and insert it on the main project at runtime!

Help me about this method or another idea. If the issue is ambiguous and you got the idea, please you edit this post to more understanding.

Thanks in advance.
Posted
Updated 25-Nov-11 11:09am
v4
Comments
Amir Mahfoozi 23-Nov-11 3:24am    
I downloaded your project and commented all the code were in Window_Loaded and replaced "MainGrid.Children.Add(factory.GetUserControl());" with "MainGrid.Children.Add(new ManyWpfControlLibrary.UserControl1());" after adding a reference to ManyWpfControlLibrary and it works like a charm.
I know you want to implement factory pattern but this could be considered as an approach. Good Luck ;)
hzawary 23-Nov-11 6:36am    
Thanks Amir for doing it, but I want implement it exactly!
hzawary 23-Nov-11 6:58am    
In fact, we have not aware about the DLL (UserControl compiled), only we load it from the diffrent assembly and insert it on the main project at runtime!
Amir Mahfoozi 23-Nov-11 7:04am    
I got the idea, I will try more but first tell me about AssemblyLoader namespace that uses reflection to load assemblies. Is it yours or you have downloaded it from somewhere ? If so please give me their homepage to see their documents...
hzawary 23-Nov-11 7:17am    
Thanks again, wish you see the issue carefully.

http://www.codeproject.com/KB/miscctrl/SelfContainedAssembly.aspx

Something like this:

C#
MyControl control = new MyControl();
this.rootGrid.Children.Add(control);
 
Share this answer
 
Comments
hzawary 22-Nov-11 10:07am    
It doesn't look comfortable! you see my problem carefully and test MyProject please.
#realJSOP 22-Nov-11 11:00am    
A lot of stuff you have to do in programming isn't comfortable. That doesn't make it "wrong". The solution i gave you is a GENERAL method for accomplishing what you orginally asked. Of course, requirements are going to dictate how you implement it in your own code, but that's not my concern.
hzawary 22-Nov-11 11:45am    
Thanks, but see you this article? http://www.codeproject.com/KB/miscctrl/SelfContainedAssembly.aspx, I've used it, only convert the project to WPF, problem is clearly.
Sergey Alexandrovich Kryukov 22-Nov-11 17:10pm    
This is irrelevant to the problem. The solution of John is correct and has nothing uncomfortable.
Actually, all controls are added like this; there is no such thing as "non-dynamic" control; the Designer does exactly this.

You are missing something. And John's answer gets my 5.
--SA
hzawary 23-Nov-11 6:32am    
Yes, and I didn't tell that the solution is incorrect, but I can not use it in the project! I want loading the any DLLs compiled (xaml+code-behind) on the main project at runtime.
Ok guys, finally! my problem was solved:-)

1) Open AssemblyInfo.cs file of ManyWpfControlLibrary.csproj .
2) Add following attribute to this file[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.MainAssembly)]
3) Build this project to get new assembly with the attribute.
4) Create *.zip from this new assembly
5) Delete older DependancyAssemblies.zip from WpfUserControlFactory.csproj
6) Add newly created zip in step 4 as embedded resource in WpfUserControlFactory.csproj.
 
Share this answer
 
Comments
Amir Mahfoozi 26-Nov-11 7:08am    
Hi I am glad to see your problem solved but I have solved it with some another anti factory pattern :
private void Button_Click(object sender, RoutedEventArgs e)
{
string path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) +
@"\plugins\WpfUserControlFactory.dll";

Assembly testAssembly = Assembly.LoadFile(path);
Type pluginType = testAssembly.GetType("WpfUserControlFactory.AssisTouchScreen");
object pluginInstance = Activator.CreateInstance(pluginType);
UserControl nuc = (UserControl)pluginType.InvokeMember("GetUserControl", BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public,
null, pluginInstance, null);
MainGrid.Children.Add(new ManyWpfControlLibrary.UserControl1());

}
hzawary 27-Nov-11 12:34pm    
Vvvvvvvvvery good;) very thanks I tried and it works like a charm!
with this
private void Button_Click(object sender, RoutedEventArgs e)
{
string path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + @"\plugins\WpfUserControlFactory.dll";
Assembly testAssembly = Assembly.LoadFile(path);
Type pluginType = testAssembly.GetType("WpfUserControlFactory.AssisTouchScreen");
object pluginInstance = Activator.CreateInstance(pluginType);
UserControl nuc = (UserControl)pluginType.InvokeMember(
"GetUserControl",
BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public,
null,
pluginInstance,
null);
MainStackPanel.Children.Add(nuc);
}

I have another a bit problem, there is way to disposing the dll? because I want update this dll file at in runtime, but when load this dll, cannot remove or modify this file, may you help me please also about this??
hzawary 27-Nov-11 12:11pm    
Thanks Amir, but this is wrong
MainGrid.Children.Add(new ManyWpfControlLibrary.UserControl1());
because there isn't the ManyWpfControlLibrary reference in the DemoClientWpfApp project!
we have only use AbstractWpfUserControlFactory and AssemblyLoader references in its!
So maybe this is your purpose MainGrid.Children.Add(new nuc);

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900