none
Command Binding not working when the host control is added programatically in wpf

    Question

  • This is weird. I have a UserControl (MyControl) with a button inside. I have added a command to this button whose command target is another user control which is again added to the same window.

    When I add the UserControl statically in xaml to the CustomControl's host space, the CommandBinding system works fine, where as the same doesn't work if the UserControl is added programatically (on Loaded event of this Window).

    What could be the reason. Am I missing something in here ?!?

    Update:

    A better representation of my words as an image. Also I have uploaded my source code with binaries @ https://code.google.com/p/commandbindingsample/

    Image @ http://codelog.blogial.com/files/scenario.png

    Thanks

    • Edited by sudarsan srinivasan Friday, October 29, 2010 10:39 AM Created a link to the scenario image
    Friday, October 29, 2010 10:37 AM

Answers

  • Hi sudarsan srinivasan

    I have analyzed carefully, and base on the analysis I understand that you want to use the button in "MyUserControl.xaml" to trigger the "Binding_Executed" event in "MyTargetControl.xaml.cs".

    If I have misunderstood your concern, please feel free let me know.

    Now I will resolve your issue first, and then analy the reason why I change this part of your source to fix your issue.

    In "MyTargetControl.xaml.cs" (change_1)

    public UserControl1()

    {

         InitializeComponent();

         CommandBinding aBinding = new CommandBinding(Commands.ClickCommand);

         aBinding.Executed += new ExecutedRoutedEventHandler(Binding_Executed);

         CommandBindings.Add(aBinding);

    }

    Change To:

    public UserControl1()

    {

         InitializeComponent();

         CommandBinding aBinding = new CommandBinding(Commands.ClickCommand);

         aBinding.Executed += new ExecutedRoutedEventHandler(Binding_Executed);

         aBinding.CanExecute += (o, ex) => { ex.CanExecute = true; };

         CommandBindings.Add(aBinding);

    }

    In "MainWindow.xaml.cs" (change_2)

    private void MainWindowName_Loaded(object sender, RoutedEventArgs e)

    {

            CommandManager.InvalidateRequerySuggested();

            MyUserControl.UserControl1 aControl = new UserControl1();

            hostPanel1.HostControl.Children.Add(aControl);

    }

    Change To:

    private void MainWindowName_Loaded(object sender, RoutedEventArgs e)

    {

         CommandManager.InvalidateRequerySuggested();

         MyUserControl.UserControl1 aControl = new UserControl1();

         hostPanel1.HostControl.Children.Add(aControl);

         Button button = aControl.FindName("button1") as Button;

         button.CommandTarget = userControl11;

    }

     

    In "MyUserControl.xaml"(change_3)  

     

    <Button Content="Click" Command="local:Commands.ClickCommand" CommandTarget="{Binding ElementName=userControl11}" />

     

    Change To:

    <Button Name="button1" Content="Click" Command="local:Commands.ClickCommand" CommandTarget="{Binding ElementName=userControl11}" />

     

    Then your app can work as you want.

     

    The reason I do those actions is:

    Change_1: To a commandbinding, both Executed and CanExecuted are necessary.

     

    Change_2: you define a button in "MyUserControl" and set the CommandTarget as "userControl1", but the userControl1 was defined in "MainWindow", this namescope can not work in your CommandTarget, so you have to use findname to complete it.

    From this link you can learn more knowledge on WPF NameScope

    http://msdn.microsoft.com/en-us/library/ms746659.aspx

     

    Change_3: just define a Name property to the Button

     

    Hope it helps!

     

    Best regards,

     

    Sheldon _Xiao


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework!
    Tuesday, November 02, 2010 8:49 AM
  • Hi sudarsan srinivasan

    I did not mean to workaround your problem, I am sorry for giving you that feeling. Now I have understood what you concern. 

    -->    I still have a question, why should the command binding bind to the target control when I write it in xaml and why not during the run time when I add the control programmatically?? 

          In WPF both in XAML and programmatically can complete command bind, for example, you can complete Click-Event by command bingding in XAML, and you also can complete by programmatically. The cause of so many people prefer to use bind in XAML is they want to use the MVVM pattern.

          there is a sample about how to programmatically creat bind for you to refer to:

          http://social.msdn.microsoft.com/forums/en-US/wpf/thread/a7cbaada-b7f2-43f4-a2b3-a672f5b8b12e/

         I hope I explained clearly to you.

    Best regards,

    Sheldon _Xiao 

         


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework!
    Thursday, November 04, 2010 6:14 AM

All replies

  • Still I have the code is not working. Can somebody help me out with this
    Sunday, October 31, 2010 5:22 AM
  • Hi sudarsan srinivasan

    Thank you for posting in our forum!  I will be working with you on this issue.

    I cannot get your source from that link. could you do actions as follow to upload your source code here?

    1 type "skydrive.live.com" in the IE address bar.

    2 sign in your account on the page, then click add files to upload your files(remember upload as "public").

    3 give me download link after upload successfully.

     

    Best regards,

    Sheldon _Xiao


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework!
    Tuesday, November 02, 2010 3:04 AM
  • Hi, 

    Thanks for replying back. I have uploaded the source code to skydrive like you have mentioned. Here is the link,

    http://cid-6fc1e241d4534589.office.live.com/embedicon.aspx/Wpf%20Samples/CommandBinding.zip

    Please revert back if you are still not able to open up the zip archive from skydrive.  

    Sudarsan Srinivasan

    Tuesday, November 02, 2010 4:36 AM
  • Hi sudarsan srinivasan

    I have analyzed carefully, and base on the analysis I understand that you want to use the button in "MyUserControl.xaml" to trigger the "Binding_Executed" event in "MyTargetControl.xaml.cs".

    If I have misunderstood your concern, please feel free let me know.

    Now I will resolve your issue first, and then analy the reason why I change this part of your source to fix your issue.

    In "MyTargetControl.xaml.cs" (change_1)

    public UserControl1()

    {

         InitializeComponent();

         CommandBinding aBinding = new CommandBinding(Commands.ClickCommand);

         aBinding.Executed += new ExecutedRoutedEventHandler(Binding_Executed);

         CommandBindings.Add(aBinding);

    }

    Change To:

    public UserControl1()

    {

         InitializeComponent();

         CommandBinding aBinding = new CommandBinding(Commands.ClickCommand);

         aBinding.Executed += new ExecutedRoutedEventHandler(Binding_Executed);

         aBinding.CanExecute += (o, ex) => { ex.CanExecute = true; };

         CommandBindings.Add(aBinding);

    }

    In "MainWindow.xaml.cs" (change_2)

    private void MainWindowName_Loaded(object sender, RoutedEventArgs e)

    {

            CommandManager.InvalidateRequerySuggested();

            MyUserControl.UserControl1 aControl = new UserControl1();

            hostPanel1.HostControl.Children.Add(aControl);

    }

    Change To:

    private void MainWindowName_Loaded(object sender, RoutedEventArgs e)

    {

         CommandManager.InvalidateRequerySuggested();

         MyUserControl.UserControl1 aControl = new UserControl1();

         hostPanel1.HostControl.Children.Add(aControl);

         Button button = aControl.FindName("button1") as Button;

         button.CommandTarget = userControl11;

    }

     

    In "MyUserControl.xaml"(change_3)  

     

    <Button Content="Click" Command="local:Commands.ClickCommand" CommandTarget="{Binding ElementName=userControl11}" />

     

    Change To:

    <Button Name="button1" Content="Click" Command="local:Commands.ClickCommand" CommandTarget="{Binding ElementName=userControl11}" />

     

    Then your app can work as you want.

     

    The reason I do those actions is:

    Change_1: To a commandbinding, both Executed and CanExecuted are necessary.

     

    Change_2: you define a button in "MyUserControl" and set the CommandTarget as "userControl1", but the userControl1 was defined in "MainWindow", this namescope can not work in your CommandTarget, so you have to use findname to complete it.

    From this link you can learn more knowledge on WPF NameScope

    http://msdn.microsoft.com/en-us/library/ms746659.aspx

     

    Change_3: just define a Name property to the Button

     

    Hope it helps!

     

    Best regards,

     

    Sheldon _Xiao


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework!
    Tuesday, November 02, 2010 8:49 AM
  • Hi,  

    Thanks for your reply.

    I feel doing the above mentioned to be more like a workaround and I am not really interested in setting the command target during the run time through c# code.

    I still have a question, why should the command binding bind to the target control when I write it in xaml and why not during the run time when I add the control programmatically??

    If you want to test this up in the sample, please navigate to the custom control's theme file and uncomment the line where I have added the user control. When you run the application now, you would see two buttons in the window - one added programmatically during the run time while the other added through the xaml (in the theme file). If you notice now, the later has the command bound to the target control properly while the previous does not. Why so??

    Thanks,  

    Sudarsan Srinivasan

    Thursday, November 04, 2010 3:57 AM
  • Hi sudarsan srinivasan

    I did not mean to workaround your problem, I am sorry for giving you that feeling. Now I have understood what you concern. 

    -->    I still have a question, why should the command binding bind to the target control when I write it in xaml and why not during the run time when I add the control programmatically?? 

          In WPF both in XAML and programmatically can complete command bind, for example, you can complete Click-Event by command bingding in XAML, and you also can complete by programmatically. The cause of so many people prefer to use bind in XAML is they want to use the MVVM pattern.

          there is a sample about how to programmatically creat bind for you to refer to:

          http://social.msdn.microsoft.com/forums/en-US/wpf/thread/a7cbaada-b7f2-43f4-a2b3-a672f5b8b12e/

         I hope I explained clearly to you.

    Best regards,

    Sheldon _Xiao 

         


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework!
    Thursday, November 04, 2010 6:14 AM
  • Hi sudaran srinivasan

    I am marking your issue as "Anwered". If you have any new findings or concerns, please unmark it.

     

    Best regards,

    Sheldon _Xiao


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework!
    Monday, November 08, 2010 1:29 AM