-1

I have a user control with a button (and more) but I want on click of that to create another instance of that user control in a main window.

Main:

UserControl mycontrol1= new UserControl();            
mainwin.Children.Add(mycontrol1); 

in mycontrol there is a button an on click I'd like to create another mycontrol2 but this does not work

UserControl mycontrol2= new UserControl();   
this.Parent.Children.Add(mycontrol2);
this.Parent.FunctionOfMainProgIWantToRUn();

I come from ActionScript world and this would run there but WPF logic is hard to get.

David Col
  • 47
  • 4
  • 1
    what is the Parent Control Type? is it a Form, Panel, StackPanel,...etc..? – MethodMan Mar 20 '13 at 16:05
  • Also what is the actual name of the UserControl..? that's where you are making a mistake in your code – MethodMan Mar 20 '13 at 16:10
  • @DJKRAZE "mainwin" is the name of the xaml grid where I am attaching mycontrol1 – David Col Mar 20 '13 at 16:19
  • I am not sure if what I was going to post will work in XAML in windows it would would you like to see an example of what I would do using your code..in Windows what is the name of your UserControl – MethodMan Mar 20 '13 at 16:22
  • 1
    `WPF logic is hard to get` - No it's not. It's simpler than anything in existance. The problem is that people don't seem to understand that [UI is Not Data](http://stackoverflow.com/questions/14381402/wpf-programming-methodology/14382137#14382137). Don't know what ActionScript is, but C# is `Statically Typed`, you can't go around calling methods that don't exist. I suggest you research on [MVVM](http://en.wikipedia.org/wiki/Model_View_ViewModel) if you expect to succeed in WPF. Also, WPF is intended to work with a proper `Architecture` and not just juggling code around here and there. – Federico Berasategui Mar 20 '13 at 16:24
  • @DJKRAZE yes please. But also if my logic here is totally off, please let me know. – David Col Mar 20 '13 at 16:25
  • HighCore I am not sure what the post has to do with the original question – MethodMan Mar 20 '13 at 16:26
  • take a look at creating the instance through `Reflection` here is a link that should help you. I do not want to confuse the issue since I am not a WPF guru http://stackoverflow.com/questions/3536080/how-to-load-a-usercontrol-in-wpf-with-reflection – MethodMan Mar 20 '13 at 16:30
  • 1
    @DJKRAZE Reflection is the last option. When you have to do something that simple with reflection, that's a sign that you're doing it wrong. – Federico Berasategui Mar 20 '13 at 16:33
  • @DavidCol Please post a screenshot of what you need and your current XAML so I can tell you the right way to implement it. Don't use reflection, it's not the right technique for what you need here. – Federico Berasategui Mar 20 '13 at 16:33
  • `MyUserControlName mycontrol2c = new MyUserControlName(); mainwin.Children.Add(mycontrol2);` not sure why this shouldn't work for you.. `REPLACE MyUserControlName` with the actual UserControl not the Type – MethodMan Mar 20 '13 at 16:36
  • @DJKRAZE: You mean the `Type` of the actual `UserControl`, not the base type `UserControl`. – Matt Burland Mar 20 '13 at 16:46
  • Yes that's what I am saying – MethodMan Mar 20 '13 at 16:47

2 Answers2

0

You are really doing this the wrong way around. The "right" way would be to have a model class that exposes a collection. You collection should then be bound to an ItemsControl (like list view) that then uses a DataTemplate to create your UserControl for each item in the list and bind it's properties.

The MVVM pattern is really worth learning about and makes WPF development much easier to manage and much easier to maintain. It looks like more work up-front, but it's really worth it in the long run.

Matt Burland
  • 44,552
  • 18
  • 99
  • 171
0

One way I can approach your question is: Using EvenHandler in Usercontrol and subscribing to it in mainView. On each say button click in Usercontrol raise the event.

I just created a sample:

we have textbox and button in Usercontrol

this is code-behind;

    public partial class UserControl1 : UserControl
{
    public event EventHandler<EventArgs> CreateNewUserControl = null;
    public static int InstanceCount = 0;
    public UserControl1()
    {
        InitializeComponent();
        Loaded += new RoutedEventHandler(UserControl1_Loaded);
    }

    void UserControl1_Loaded(object sender, RoutedEventArgs e)
    {
        InstanceCount++;
        txtControl.Text = "Control - " + InstanceCount;
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        var handler = CreateNewUserControl;
        if (handler != null)
         handler.Invoke(sender,e);
    }
}

In MainView:

Xaml:

   <StackPanel x:Name="UserControlTest" Orientation="Vertical" VerticalAlignment="Top" HorizontalAlignment="Right" Grid.Column="1" Grid.RowSpan="2" ScrollViewer.VerticalScrollBarVisibility="Auto" MaxHeight="800" Margin="30">

            <RadChartProject:UserControl1 x:Name="UserControl1"/>

        </StackPanel>

xaml.cs:

      public MainPage()
    {
        InitializeComponent();

        UserControl1.CreateNewUserControl += UserControl1_CreateNewUserControl;
    }

    void UserControl1_CreateNewUserControl(object sender, EventArgs e)
    {
        if(UserControlTest != null)
        {
            var control = new UserControl1();
            control.CreateNewUserControl += UserControl1_CreateNewUserControl;
            UserControlTest.Children.Add(control);
        }
    }
MSNetDev
  • 141
  • 9
  • Thank you! I tested it and it works great. This is exactly what I needed! – David Col Mar 20 '13 at 19:13
  • One more thing... I can not figure out how do I know in MainView which button sent the click? – David Col Mar 20 '13 at 19:46
  • In my example sender is nothing but a button. var button = (sender as button). now you know which button it is. Best way is assign some unique value to button commandparameter. – MSNetDev Mar 20 '13 at 21:12