locked
XAML UserControl which acts like a container for other Controls

    Question

  • Hello everybody. I try to implement a UserControl which acts like a container for other Controls (like Grid, StackPanel, etc..) and also holds Its own Controls. My code looks like this:
    UserControl.xaml

    <UserControl Name="Control"
                 ........... >
    
        <StackPanel Orientation="Vertical">
            <Button Content="Test Button inside of UserControl" Click="btnTest_Click" Foreground="Black"/>
            <Border BorderBrush="#C2C2C2" BorderThickness="1,0,0,0" Grid.Row="1">        
            <!-- Content -->
                <ContentPresenter Content="{Binding ElementName=Control, Path=MyContent}" />
            </Border>
        </StackPanel>
    </UserControl>
    UserControl.xaml.h
    	public ref class MyControl sealed 
    	{
    	public:
    		MyControl();
    		property Windows::UI::Xaml::FrameworkElement^ MyContent
    		{
    			Windows::UI::Xaml::FrameworkElement^ get() {
    				return (Windows::UI::Xaml::FrameworkElement^)GetValue(ContentProperty);
    			}
    			void set(Windows::UI::Xaml::FrameworkElement^ value) {
    				SetValue(ContentProperty, value);
    			}
    		}
    		static property Windows::UI::Xaml::DependencyProperty^ ContentProperty
    		{
    			Windows::UI::Xaml::DependencyProperty^ get() { return m_content; }
    		}
    	private:
    		static Windows::UI::Xaml::DependencyProperty^ m_content;
    		void btnTest_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
    	};
    UserControl.xaml.cpp
    DependencyProperty^ MyControl::m_content = 
    	DependencyProperty::Register("MyContent", FrameworkElement::typeid, MyControl::typeid, nullptr);
    
    MyControl::MyControl()
    {
    	InitializeComponent();
    }
    
    void MyControl::btnTest_Click(Object^ sender, RoutedEventArgs^ e)
    {
        //Empty for now
    }

    Usage of this Control inside of MainPage.xaml
                    <ctr:MyControl x:Name="myControlTest" >
                        <ctr:MyControl.MyContent>
                            <Button Foreground="Black" Content="Button from MainPage"
                                x:Name="btnMainPage" Click="btnMainPage_Click"/>
                        </ctr:MyControl.MyContent>
                    </ctr:MyControl>
    When I run my app both buttons are displayed. However I can`t do anything with button from MainPage because btnMainPage == nullptr inside of code behind of MainPage.xaml. How can I fix this to manipulate Controls added to MyControl?

    Thanks in advance.


    • Edited by RenGate Thursday, August 30, 2012 12:29 PM fixed typo
    Tuesday, August 28, 2012 5:08 PM

Answers

  • I see. "How can I fix this to manipulate Controls added to MyControl":

    - your technique of choice is to use DataTemplates to profile the content of MyControl: see "ContentControl.ContentTemplate". You set the appropriate data template based on some property in your view model you'd bind to.

    - if - in addition - you need to adapt a particular child control within that chosen data template, then

    -- you'd do it in code-behind within the child user control or from within the parent user control

    -- if the parent user control is the one that must contains the logic, then you need 'VisualTreeHelper' to walk the visual tree downwards. However you can only do that once the child UIElements are realized (exist), which you can ascertain using 'ContentControl.ApplyTemplate()' beforehand. Needless to say that such technique is quite advanced and requires some experimentation.


    • Edited by ForInfo Wednesday, September 5, 2012 7:27 AM
    • Marked as answer by RenGate Wednesday, September 5, 2012 1:16 PM
    Wednesday, September 5, 2012 7:08 AM

All replies

  • Hi,

    I am not sure I understand what is "SettingsFlyout" . Also, when you run the application, is there any exception in the "Output" window. You can use the DebugSettings::BindingFailed event to debug runtime binding failures.

    -Sagar

    Thursday, August 30, 2012 11:06 AM
    Moderator
  • Hello, thank you for answer. "SettingsFlyout" is just a typo. There are no exceptions in the Output window and attached event handler to DebugSettings::BindingFailed does not get invoked during app execution.
    Thursday, August 30, 2012 12:55 PM
  • Anyone? It seems that I must change the return type of MyContent property from Windows::UI::Xaml::FrameworkElement^ to something else.
    Tuesday, September 4, 2012 1:14 PM
  • "However I can`t do anything with button from MainPage because btnMainPage == nullptr inside of code behind of MainPage.xaml"

    - do you really need "x:Name="btnMainPage"

    - the 'sender' should reference the Button in the Click event handler, without the need to access it by name.



    • Edited by ForInfo Tuesday, September 4, 2012 3:44 PM
    Tuesday, September 4, 2012 3:42 PM
  • Yes, I do really need such functionality because in a real app there will be not only buttons but also a ComboBoxes or other controls which require the x:Name parameter to populate them, change the attributes, etc from the code behind.
    Tuesday, September 4, 2012 6:50 PM
  • I see. "How can I fix this to manipulate Controls added to MyControl":

    - your technique of choice is to use DataTemplates to profile the content of MyControl: see "ContentControl.ContentTemplate". You set the appropriate data template based on some property in your view model you'd bind to.

    - if - in addition - you need to adapt a particular child control within that chosen data template, then

    -- you'd do it in code-behind within the child user control or from within the parent user control

    -- if the parent user control is the one that must contains the logic, then you need 'VisualTreeHelper' to walk the visual tree downwards. However you can only do that once the child UIElements are realized (exist), which you can ascertain using 'ContentControl.ApplyTemplate()' beforehand. Needless to say that such technique is quite advanced and requires some experimentation.


    • Edited by ForInfo Wednesday, September 5, 2012 7:27 AM
    • Marked as answer by RenGate Wednesday, September 5, 2012 1:16 PM
    Wednesday, September 5, 2012 7:08 AM
  • Thank you for answer. I think it gives all information I need.
    Wednesday, September 5, 2012 1:16 PM