Page 1 of 1

How to place a XAML usercontrol in a grid

Posted: 18 Nov 2014, 11:01
by blub7
I want to switch between several user controls, i.e. UserControl1, UserControl2, UserControl3, using several buttons where each button is associated with one particular UserControl.

I've built a very primitive UserControl containing simple Sliders, RadioButtons, and CheckBoxes. I named it UserControl1, deleted the corresponding CodeBehind file, and removed the x:Class property. Now, I'd like to integrate UserControl1 to my MainUserControl. When I do this using Blend, I don't get an error; however, there is an exclamation mark in the preview. When I try to re-build the code in Blend, I get a warning saying that I should re-build the code again, and again and again.

When I run my code in Unity, I get the following warning.
Ignoring unknown type 'NoesisApp.UserControl1' (@519,7)
The code runs, but the UserControl is not shown.

Does anyone see what I am doing wrong here?

My MainUserControl looks like this:
<UserControl
    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:TestApp;assembly=TestApp"
    mc:Ignorable="d"
    x:Name="UserControl"
    xmlns:cntrl="clr-namespace:TestApp"
    d:DesignWidth="640" d:DesignHeight="480">
    <UserControl.Triggers>
        <EventTrigger RoutedEvent="ToggleButton.Checked" SourceName="Cntrl1">
            <BeginStoryboard Storyboard="{StaticResource ActivateCntrl1}"/>
        </EventTrigger>
        <EventTrigger RoutedEvent="ToggleButton.Checked" SourceName="Cntrl2">
            <BeginStoryboard Storyboard="{StaticResource ActivateCntrl2}"/>
        </EventTrigger>
        <EventTrigger RoutedEvent="ToggleButton.Checked" SourceName="Cntrl3">
            <BeginStoryboard Storyboard="{StaticResource ActivateCntrl3}"/>
        </EventTrigger>
    </UserControl.Triggers>
    <Viewbox>
        <Grid x:Name="LayoutRoot" Height="540" Width="1440">
            <Grid.Background>
                <LinearGradientBrush EndPoint="0.916,0.431" StartPoint="0.022,0.879">
                    <GradientStop Color="Black" Offset="0"/>
                    <GradientStop Color="White" Offset="1"/>
                </LinearGradientBrush>
            </Grid.Background>
            <Ellipse HorizontalAlignment="Left" Height="80" Margin="46.5,223.5,0,0" Stroke="Black" VerticalAlignment="Top" Width="80" StrokeThickness="0" Opacity="0.7">
                <Ellipse.Fill>
                    <RadialGradientBrush>
                        <GradientStop Color="#FF3250DC" Offset="0"/>
                        <GradientStop Color="#FF14143C" Offset="0.905"/>
                        <GradientStop Color="#FF282864" Offset="0.672"/>
                    </RadialGradientBrush>
                </Ellipse.Fill>
            </Ellipse>
            <Button Content="Button" HorizontalAlignment="Left" Margin="46,13.5,0,0" VerticalAlignment="Top" Width="75"/>
            <Grid HorizontalAlignment="Left" Height="482.5" Margin="756,28.5,0,0" VerticalAlignment="Top" Width="640">
                                <StackPanel x:Name="Cntrl1Badge" Margin="0,0,0,0" Orientation="Vertical" RenderTransformOrigin="0.5,0.5">
                        <StackPanel.RenderTransform>
                            <TransformGroup>
                                <ScaleTransform/>
                                <SkewTransform/>
                                <RotateTransform/>
                                <TranslateTransform/>
                            </TransformGroup>
                        </StackPanel.RenderTransform>
                        <Border x:Name="Cntrl1Border" Width="640" Height="482.5" BorderThickness="2">
                            <Border.BorderBrush>
                                <SolidColorBrush Color="#7F666666" Opacity="1"/>
                            </Border.BorderBrush>
                            <Border.Background>
                                <RadialGradientBrush Opacity="1">
                                    <GradientStop Color="#CCBEBEBE" Offset="0"/>
                                    <GradientStop Color="#E53C3096" Offset="1"/>
                                </RadialGradientBrush>
                            </Border.Background>
                            <cntrl:UserControl1/>
                        </Border>
                    </StackPanel>
                    <StackPanel x:Name="Cntrl2Badge" Margin="0,0,0,0" Orientation="Vertical" RenderTransformOrigin="0.5,0.5" HorizontalAlignment="Right" Width="640">
                        <StackPanel.RenderTransform>
                            <TransformGroup>
                                <ScaleTransform/>
                                <SkewTransform/>
                                <RotateTransform/>
                                <TranslateTransform/>
                            </TransformGroup>
                        </StackPanel.RenderTransform>
                        <Border x:Name="Cntrl2Border" Width="640" Height="482.5" BorderThickness="2">
                            <Border.BorderBrush>
                                <SolidColorBrush Color="#7F666666" Opacity="1"/>
                            </Border.BorderBrush>
                            <Border.Background>
                                <RadialGradientBrush Opacity="1">
                                    <GradientStop Color="#CCBEBEBE" Offset="0"/>
                                    <GradientStop Color="#E53C3096" Offset="1"/>
                                </RadialGradientBrush>
                            </Border.Background>
                            <cntrl:UserControl2/>
                        </Border>
                    </StackPanel>
                    <StackPanel x:Name="Cntrl3Badge" Margin="0,0,0,0" Orientation="Vertical" RenderTransformOrigin="0.5,0.5">
                        <StackPanel.RenderTransform>
                            <TransformGroup>
                                <ScaleTransform/>
                                <SkewTransform/>
                                <RotateTransform/>
                                <TranslateTransform/>
                            </TransformGroup>
                        </StackPanel.RenderTransform>
                        <Border x:Name="Cntrl3Border" Width="640" Height="482.5" BorderThickness="2" Margin="5,0">
                            <Border.BorderBrush>
                                <SolidColorBrush Color="#7F666666" Opacity="1"/>
                            </Border.BorderBrush>
                            <Border.Background>
                                <RadialGradientBrush Opacity="1">
                                    <GradientStop Color="#CCBEBEBE" Offset="0"/>
                                    <GradientStop Color="#E53C3096" Offset="1"/>
                                </RadialGradientBrush>
                            </Border.Background>
                            <cntrl:UserControl3/>
                        </Border>
                    </StackPanel>
            </Grid>
            <StackPanel HorizontalAlignment="Left" Height="441.25" Margin="262.5,89.25,0,0" VerticalAlignment="Top" Width="397">
                <ToggleButton x:Name="Cntrl1" Style="{StaticResource MenuButtonStyle}" Content="ALEX" Height="81.96"/>
                <ToggleButton x:Name="Cntrl2" Style="{StaticResource MenuButtonStyle}" Content="SEVGI" Height="81.96"/>
                <ToggleButton x:Name="Cntrl3" Style="{StaticResource MenuButtonStyle}" Content="MICHL" Height="81.96"/>
            </StackPanel>
        </Grid>
    </Viewbox>
</UserControl>
And UserControl1 looks like this:
<UserControl
    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"
    mc:Ignorable="d"
    x:Name="UserControl"
    d:DesignWidth="640" d:DesignHeight="482.5">

    <Grid x:Name="LayoutRoot">
        <Slider HorizontalAlignment="Left" Margin="47.5,16,0,0" VerticalAlignment="Top" Width="534" Height="27.956"/>
        <Slider HorizontalAlignment="Left" Margin="47.5,78.266,0,0" VerticalAlignment="Top" Width="534" Height="27.957"/>
        <Slider HorizontalAlignment="Left" Margin="47.5,145.616,0,0" VerticalAlignment="Top" Width="534" Height="27.956"/>
        <Slider HorizontalAlignment="Left" Margin="47.5,211.694,0,0" VerticalAlignment="Top" Width="534" Height="27.957"/>
        <Slider HorizontalAlignment="Left" Margin="47.5,275.231,0,0" VerticalAlignment="Top" Width="534" Height="27.957"/>
        <RadioButton Content="RadioButton" HorizontalAlignment="Left" Margin="76.144,362.913,0,0" VerticalAlignment="Top" Height="20.281" Width="167.586"/>
        <CheckBox Content="CheckBox" HorizontalAlignment="Left" Margin="80.236,423.908,0,0" VerticalAlignment="Top" Height="20.281" Width="139.985"/>
        <RadioButton Content="RadioButton" HorizontalAlignment="Left" Margin="358.489,364.183,0,0" VerticalAlignment="Top" Height="20.281" Width="167.585"/>
        <CheckBox Content="CheckBox" HorizontalAlignment="Left" Margin="360.534,425.179,0,0" VerticalAlignment="Top" Height="20.281" Width="139.986"/>
    </Grid>
</UserControl>
Note, for the sake of clarity I removed the Styles from MainUserControl. Therefore, this XAML might not be working.

Re: How to place a XAML usercontrol in a grid

Posted: 19 Nov 2014, 10:13
by sfernandez
Hi,

If you want to use a UserControl by referencing it by its class name in a XAML, you have to provide a code behind class. That way, the type name can be resolved to the corresponding UserControl class and the associated XAML can be loaded. So you must add the x:Class and code-behind to UserControl1, UserControl2 and UserControl3.

If you just want to add some xaml to a panel or container, you can do it in code by loading the xaml manually:
UserControl uc1 = NoesisGUISystem.LoadXaml<UserControl>("Assets/UserControls/UserControl1.xaml");
_cntrl1Border.SetChild(uc1);

Re: How to place a XAML usercontrol in a grid

Posted: 19 Nov 2014, 11:23
by blub7
I am just wondering where to find information like this in the Documentation?

It still doesn't work. I just created a new Control and kept the CodeBehind File, which looks like this:
using System;
using System.Collections.Generic;
using System.Text;
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 NoesisApp
{
	/// <summary>
	/// Interaction logic for Control2.xaml
	/// </summary>
	public partial class Control2 : UserControl
	{
		public Control2()
		{
			this.InitializeComponent();
		}
	}
}
When I run my code in Unity, I get the following error:
Assets/NoesisApp/Control2.xaml.cs(4,14): error CS0234: The type or namespace name `Windows' does not exist in the namespace `System'. Are you missing an assembly reference?

Re: How to place a XAML usercontrol in a grid

Posted: 19 Nov 2014, 11:44
by sfernandez
Hi,

You can find more info on how to create your own UserControls in the following tutorial: http://www.noesisengine.com/docs/Gui.Co ... unity.html

The errors you are getting are because you are using the namespaces from Windows, that are not available for Unity's Mono framework. You won't be able to directly use the code-behind generated by Blend for your UserControl, you have to adapt it as explained in the aforementioned tutorial. Please note the required class attributes [Noesis.Extended] and [Noesis.UserControlSource], and the use of PostInit() function to initialize the control variables and event handlers.

Your UserControl code-behind would look like this to be used in Unity (assuming the Control2.xaml is placed in the root Assets folder):
using System;
using Noesis;

namespace NoesisApp
{
   /// <summary>
   /// Interaction logic for Control2.xaml
   /// </summary>
   [Extended]
   [UserControlSource("Assets/Control2.xaml")]
   public partial class Control2 : UserControl
   {
      public Control2()
      {
      }
   }
}
Hope this helps.

Re: How to place a XAML usercontrol in a grid

Posted: 19 Nov 2014, 13:15
by blub7
Thank you!

Re: How to place a XAML usercontrol in a grid

Posted: 21 Nov 2014, 23:02
by movra
From the UserControl documentation for Unity:
The attribute x:Name indicates the class that implements the code-behind.
x:Name should be x:Class?

Re: How to place a XAML usercontrol in a grid

Posted: 23 Nov 2014, 14:08
by jsantos
Yes, it is a typo. Thanks!

Re: How to place a XAML usercontrol in a grid

Posted: 24 Feb 2015, 18:48
by movra
Yes, it is a typo. Thanks!
That typo is still in the 1.2 RC2 documentation.

Re: How to place a XAML usercontrol in a grid

Posted: 24 Feb 2015, 18:52
by jsantos
Yes, the UserControl and CustomControl tutorials are yet outdated. I have that fixed in the new document, but I am not sure when we will made them public because I wanted to wait for having support for code-behind events in c#.

So, I fixed the old one at least. :)

Thanks!