Problems with dynamic height in Windows Phone 8 (see sketch inside) - c#

I'm currently fiddling with a Windows Phone 8 Gui but i have run into some problems. The idea is rather simple:
There's a scrollviewer in the App that has 3 items in it. One of them (A) is always visible and has a fixed height. The two others (B and C) are supposed to have a dynamic height that uses the rest of the available screenspace in the scrollviewer (see sketch)
I have not been able to either
1) Find a XAML definitions that allows me to set-up the layout in the described way. The main Problem is getting the content in the scrollviewer to automatically have the correct height for the scrolling to happen and everything to line up exactly.
or
2) Dynamically set the correct height for all items in the code behind. My main problem here is getting the heights of the dynamically sized objects. Whatever i try i either get 0,0 or 0 or NaN.
here is the XAML code i have so far
<phone:PhoneApplicationPage
x:Class="PhoneApp1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible="True">
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="224"/>
<RowDefinition/>
</Grid.RowDefinitions>
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="0,0,0,108">
<TextBlock x:Name="subtitle" Text="Help Me" Style="{StaticResource PhoneTextNormalStyle}" Margin="12,0"/>
<TextBlock x:Name="title" Margin="0" Style="{StaticResource PhoneTextTitle1Style}">
<Run Text="StackOverflow"/>
<Run Text="!"/>
</TextBlock>
</StackPanel>
<Grid x:Name="ContentPanel" Margin="0,136,0,0" Grid.RowSpan="2">
<ScrollViewer x:Name="mainScrollViewer" HorizontalAlignment="Left" VerticalAlignment="Top" Height="633" Margin="0">
<Grid x:Name="contentGrid" HorizontalAlignment="Left" VerticalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="300"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--Here are my Elements A, B, C -->
<Image x:Name="element_B" Grid.Row="0" Stretch="Fill" Source="/Assets/b5xhG.png"/>
<Image x:Name="element_A" Grid.Row="1" Stretch="Fill" Source="/Assets/b5xhG.png"/>
<Image x:Name="element_C" Grid.Row="2" Stretch="Fill" Source="/Assets/b5xhG.png"/>
</Grid>
</ScrollViewer>
</Grid>
</Grid>
</phone:PhoneApplicationPage>
and here's my minimal code behind
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using PhoneApp1.Resources;
namespace PhoneApp1
{
public partial class MainPage : PhoneApplicationPage
{
// Konstruktor
public MainPage()
{
InitializeComponent();
/*when the app starts, the height of the ContentGrid should be equal to the height of the Scrollviewer,
* therefore the height that element A and B should be together*/
var BAndCHeight = contentGrid.Height - element_A.Height;
/*with that in mind, the new height of the Content in the Scrollviewer should be */
var contentGridSupposedHeight = 2 * BAndCHeight + element_A.Height;
}
}
}
Can anyone give me a hint how this is supposed to be done? Maybe I'm missing something. If not, how do i get the correct heights of the Elements so i can scale them myself?
Thanks for your help!

You may want to try ActualHeight instead of Height.
This Should give the current height of the elements.
var BAndCHeight = contentGrid.ActualHeight - element_A.ActualHeight;
This may only be used during or after the Loaded event because the elements are actually rendered during the Loaded event.
I hope this helps.

I think no need to set dynamically height of any element, Your issue should be resolved in your xaml. May this will help you, You can copy paste xaml.
<phone:PhoneApplicationPage
x:Class="PhoneApp1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible="True">
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel x:Name="TitlePanel" Grid.Row="0" >
<TextBlock x:Name="subtitle" Text="Help Me" Style="{StaticResource PhoneTextNormalStyle}" Margin="12,0"/>
<TextBlock x:Name="title" Margin="0" Style="{StaticResource PhoneTextTitle1Style}">
<Run Text="StackOverflow"/>
<Run Text="!"/>
</TextBlock>
</StackPanel>
<Grid x:Name="ContentPanel" Margin="0,10,0,0" Grid.Row0="1">
<ScrollViewer x:Name="mainScrollViewer" Margin="0">
<Grid x:Name="contentGrid" HorizontalAlignment="Left" VerticalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!--Here are my Elements A, B, C -->
<Image x:Name="element_B" Grid.Row="0" Stretch="Fill" Source="/Assets/b5xhG.png"/>
<Image x:Name="element_A" Grid.Row="1" Stretch="Fill" Source="/Assets/b5xhG.png"/>
<Image x:Name="element_C" Grid.Row="2" Stretch="Fill" Source="/Assets/b5xhG.png"/>
</Grid>
</ScrollViewer>
</Grid>
</Grid>
</phone:PhoneApplicationPage>

To get the sizes right in the contentGrid, try this:
Set all your row heights to "Auto" in XAML
Then in your Loaded event handler, find which row has the largest ActualHeight and then set the heights of the other two rows to size "*"
void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
{
double h = -1;
for (int row = 0; row < 3; row++)
if (contentGrid.RowDefinitions[row].ActualHeight > h)
h = contentGrid.RowDefinitions[row].ActualHeight;
for (int row = 0; row < 3; row++)
if (contentGrid.RowDefinitions[row].ActualHeight < h)
contentGrid.RowDefinitions[row].Height = new GridLength(1, GridUnitType.Star);
}
contentGrid.RowDefinitions[tallestRow].Height = System.Windows.GridLength.Auto;
}

Related

Resizing of ToolWindow and contents in WPF

We have a VS extension. The user uses a ToolWindowPane to interact with the extension. The height and width of the ToolWindowPane depends on how the user has their VS environment set up, and currently the contents of the ToolWindowPane does not resize properly.
So here is the window:
public class SymCalculationUtilitiesWindow : ToolWindowPane
{
/// <summary>
/// Initializes a new instance of the <see cref="SymCalculationUtilitiesWindow"/> class.
/// </summary>
public SymCalculationUtilitiesWindow() : base(null)
{
this.Caption = "Sym Calculation Utilities";
this.ToolBar = new CommandID(new Guid(Guids.guidConnectCommandPackageCmdSet), Guids.SymToolbar);
// This is the user control hosted by the tool window; Note that, even if this class implements IDisposable,
// we are not calling Dispose on this object. This is because ToolWindowPane calls Dispose on
// the object returned by the Content property.
this.Content = new UtilitiesView();
}
}
So the UtilitiesView is the default view. Here is the xaml:
<UserControl
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"
xmlns:local="clr-namespace:Sym.VisualStudioExtension" x:Class="Sym.VisualStudioExtension.Engines.UtilitiesView"
xmlns:engines="clr-namespace:Sym.VisualStudioExtension.Engines"
Background="{DynamicResource VsBrush.Window}"
Foreground="{DynamicResource VsBrush.WindowText}"
mc:Ignorable="d"
local:ViewModelLocator.AutoWireViewModel="True"
x:Name="MyToolWindow" Height="800" Width="400">
<UserControl.Resources>
<DataTemplate DataType="{x:Type engines:CalcEngineViewModel}">
<engines:CalcEngineView/>
</DataTemplate>
<DataTemplate DataType="{x:Type engines:TAEngineViewModel}">
<engines:TAEngineView/>
</DataTemplate>
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="207*" />
<RowDefinition Height="593*"/>
</Grid.RowDefinitions>
<Grid x:Name="MainContent"
Grid.Row="1" Grid.RowSpan="2">
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<ContentControl Content="{Binding CurrentEngineViewModel}" Grid.RowSpan="2"/>
</Grid>
</Grid>
and the user makes a choice which determines the CurrentEngineViewModel.
The following is the xaml of one of the possible CurrentEngineViewModels:
<UserControl x:Class="Sym.VisualStudioExtension.Engines.CalcEngineView"
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"
xmlns:domain="clr-namespace:Sym.Engines.Calculation.Builder.Domain;assembly=Sym.Engines.Calculation"
xmlns:core="clr-namespace:Sym.Core.Domain;assembly=Sym.Core"
xmlns:helper="clr-namespace:Sym.VisualStudioExtension.Helper_Classes"
xmlns:local="clr-namespace:Sym.VisualStudioExtension"
local:ViewModelLocator.AutoWireViewModel="True"
mc:Ignorable="d"
d:DesignHeight="800" d:DesignWidth="400">
<UserControl.Resources>
<ContextMenu>
...
</ContextMenu>
</UserControl.Resources>
<Grid Margin="-20,-20,-20,-20">
<Grid.RowDefinitions>
<RowDefinition Height="8*"/>
</Grid.RowDefinitions>
<TabControl x:Name="tabControl" HorizontalAlignment="Left" Height="617" Margin="20,54,0,0" VerticalAlignment="Top" Width="357">
<TabItem Header="Calculation Files">
<ListBox Name="CalcFilesListBox"
Margin="20" ItemsSource="{Binding CalcFilesList}"
ContextMenu="{StaticResource NewEditDeleteContextMenu}"
Tag="{x:Type core:CalcFile}">
...
</ListBox>
</TabItem>
<TabItem Header="Template Files" Height="22" VerticalAlignment="Top">
<TreeView ItemsSource="{Binding TemplateFamilyList}"
Margin="20"
ContextMenu="{StaticResource NewEditDeleteContextMenu}"
Tag="{x:Type domain:TemplateParameter}">
<TreeView.Resources>
...
</TreeView.Resources>
</TreeView>
</TabItem>
<TabItem Header="Advanced Calc Files">
<ListBox Margin="20"
ItemsSource="{Binding AdvancedCalcFilesList}"
ContextMenu="{StaticResource NewEditDeleteContextMenu}"
Tag="{x:Type domain:TemplateCalculation}">
...
</ListBox>
</TabItem>
</TabControl>
<Label x:Name="label" Content="{Binding Path=Title}" HorizontalAlignment="Left" Height="27" Margin="10,22,0,0" VerticalAlignment="Top" Width="367"/>
</Grid>
It seems to me that on the ToolWindowPane, there is a Grid, and on the Grid another Grid, and on that Grid, a Tabcontrol. From this post it seems that some controls do not resize. So would that mean that the TabControl can't resize even if it is on a Grid?
When the user resizes the ToolWindowPane, the contents does not resize.
How can I achieve correct resizing in this situation?
The base of the problem is the explicit Width and Height values are being set and preventing the controls from fitting into their container.
To make the page salable across resolutions/devices, you must ensure that there are no fixed width/height property specified; instead we can use them in percentage (%) which will make the controls scale based on available viewport. Try replacing all the fixed height & width properties for your control with percentages.
if for some reasons the controls are getting squeezed you can try providing minHeight & minWidth to the control as documented here https://www.w3schools.com/cssref/pr_dim_min-height.asp

WPF Border shape

I want to create a popup like the one that Lync 2013 has:
What I´m interested in, is to create a control with that vignette shape.
I have tried creating a UserControl with a Canvas inside and a Path with the shape. But I was not finding Canvas very friendly, so I was wondering if I can achieve this by "playing" with the Border control, so as to put only a border and then a grid inside.
Is this possible? Can somebody help me to be in the right track?
This is my XAML:
<Window x:Class="CustomBorderStyle.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
LocationChanged="Window_LocationChanged"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Border BorderBrush="Silver" BorderThickness="1">
<Button Content="Nice image button" Name="btnThingToClick" Width="100" Height="100" Click="btnThingToClick_Click" />
</Border>
<Popup Name="myPopup"
AllowsTransparency="True"
PlacementTarget ="{Binding ElementName=btnThingToClick}"
Placement="Custom">
<Grid x:Name="grid" Height="200" Width="200" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="40"/>
</Grid.RowDefinitions>
<Border BorderBrush="Silver" BorderThickness="1" Background="White" CornerRadius="5" Grid.Row="0" Padding="5">
<StackPanel Orientation="Vertical">
<TextBlock Text="Some stuff" />
<Button Content="Click me" Width="50" />
</StackPanel>
</Border>
<Path Fill="White" Stretch="Fill" Stroke="Silver" HorizontalAlignment="Left" Margin="30,-1.6,0,0" Width="25" Grid.Row="1"
Data="M22.166642,154.45381 L29.999666,187.66699 40.791059,154.54395"/>
</Grid>
</Popup>
</Grid>
</Window>
This is my code behind for the main window:
using System;
using System.Collections.Generic;
using System.Linq;
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;
using System.Windows.Controls.Primitives;
namespace CustomBorderStyle
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
//wire up the popup to the popup placement method
myPopup.CustomPopupPlacementCallback = new CustomPopupPlacementCallback(placePopup);
}
private void btnThingToClick_Click(object sender, RoutedEventArgs e)
{
//just invert if it's open or not
myPopup.IsOpen = !myPopup.IsOpen;
}
//this is to position the popup next to the button
public CustomPopupPlacement[] placePopup(Size popupSize,
Size targetSize,
Point offset)
{
CustomPopupPlacement placement1 =
new CustomPopupPlacement(new Point(10, -200), PopupPrimaryAxis.Vertical);
CustomPopupPlacement placement2 =
new CustomPopupPlacement(new Point(10, 20), PopupPrimaryAxis.Horizontal);
CustomPopupPlacement[] ttplaces =
new CustomPopupPlacement[] { placement1, placement2 };
return ttplaces;
}
private void Window_LocationChanged(object sender, System.EventArgs e)
{
//if the popup is open when the window's location changes
if (myPopup.IsOpen)
{
//toggle the popup to redraw the location
myPopup.IsOpen = false;
myPopup.IsOpen = true;
}
}
}
}
You will obviously need some nice images to use for the buttons and some better stuff to put in the stackpanel so the popup looks nice, but that should do the job :)
The thing you have to be careful with is the positioning of the popup, this means if you change the height of the popup by adding more stuff you need to change the values of the "CustomPopupPlacement" objects, there might be a nice way to fix this??
I just wanted to paste some code that works for me:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Popup Placement="Top"
IsOpen="{Binding SettingsVisible}"
PopupAnimation="Fade"
AllowsTransparency="True">
<Grid Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Border Grid.Row="0" CornerRadius="10" Background="SkyBlue" HorizontalAlignment="Left">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0">Hello, world</TextBlock>
<Button Grid.Row="1">Click Me!</Button>
</Grid>
</Border>
<Path Grid.Row="1" VerticalAlignment="Bottom" Data="M 10 0 L 20 10 L 30 0 Z" Fill="SkyBlue" />
</Grid>
</Popup>
<Button Grid.Column="0" HorizontalAlignment="Left" Command="{Binding ToggleSettingsVisibility}">Settings</Button>
<Button x:Uid="Button_1" IsEnabled="{Binding SettingsVisible}" Grid.Column="1" HorizontalAlignment="Right" Padding="30, 10" Command="{Binding Next}">Next</Button>
</Grid>
My example features two buttons, important for this example is the 1st one (it is part of a wizard-like UI, but you can ignore the 2nd button).
I don't have the ViewModel here, but the mechanism is simple, the Settings-Button binds against the property ToggleSettingsVisibility which sets the SettingsVisibility the Popup binds against. All that is not really important for the example.
The result looks like this:
Of course, I still have to work on the styling ;-)

Windows Phone 8 XAML Editor setting variables to null at runtime

I've been trying to add a simple TextBlock control to my Windows Phone 8 app, however once I assign it a name in the GUI XAML editor and attempt to access the control via its assigned name in the C# code at runtime I get "NullReferenceExceptions" because the variable is never set.
I have narrowed the problem down to the PhoneApplicationPage method "FindName" i.e.
PhoneApplicationPage.FindName("videoName");
However a call like this to some of my controls (created in the GUI editor) simply return null. Has anybody had this problem and found a fix?
Regards.
The contents of the InitialiseComponent() method:
public void InitializeComponent() {
if (_contentLoaded) {
return;
}
_contentLoaded = true;
System.Windows.Application.LoadComponent(this, new System.Uri("/Youtube%20Downloader;component/MainPage.xaml", System.UriKind.Relative));
this.LayoutRoot = ((System.Windows.Controls.Grid)(this.FindName("LayoutRoot")));
this.TitlePanel = ((System.Windows.Controls.StackPanel)(this.FindName("TitlePanel")));
this.ContentPanel = ((System.Windows.Controls.Grid)(this.FindName("ContentPanel")));
this.videoName = ((System.Windows.Controls.TextBlock)(this.FindName("videoName")));
this.videoImage = ((System.Windows.Controls.Image)(this.FindName("videoImage")));
}
(The videoName and videoImage controls are the ones not getting added)
The XAML code is (that the editor has generated):
<phone:PhoneApplicationPage
x:Class="Youtube_Downloader.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible="True">
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock Text="YOUTUBE DOWNLOADER" Style="{StaticResource PhoneTextNormalStyle}" Margin="12,0"/>
</StackPanel>
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<TextBlock x:Name="videoName" Margin="10,10,0,0" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top" Height="56" FontSize="36" FontStyle="Normal"/>
<Image x:Name="videoImage" HorizontalAlignment="Center" Height="408" Margin="0,72,0,0" VerticalAlignment="Top" Width="446"/>
</Grid>
</Grid>
I had the same problem. Clean project will fix it.

showing Image swapping like picture gallery in Windows Phone C#

I am not able to make smooth swapping like image gallery in windows phone.
I tried flip gesture listener and its able to swap image but its not swapping smoothly.
I tried to search but didn't got any answer. I am trying to show a list of images in gallery view manner.I am struggling from past 3 days. Please it will be a help if you give me some suggestion or link.
This is a simple example i just built to show you how it has to be done.. hope u find it helpful
<phone:PhoneApplicationPage xmlns:Controls="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls"
x:Class="PhotoChooser.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible="True">
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--TitlePanel contains the name of the application and page title-->
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock x:Name="ApplicationTitle" Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock x:Name="PageTitle" Text="page name" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<ListBox x:Name="lbImages">
<ListBox.ItemTemplate>
<DataTemplate>
<Controls:Panorama>
<Controls:PanoramaItem>
<Image Source="{Binding ImageName}"/>
</Controls:PanoramaItem>
</Controls:Panorama>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Grid>
and the class file for this designer goes something like this
public partial class MainPage : PhoneApplicationPage
{
public MainPage()
{
InitializeComponent();
PanoramaItem panItem = new PanoramaItem();
List<ImageList> imgList = new List<ImageList>();
imgList.Add(new ImageList() { ImageName = ImagePath.Image4 });
lbImages.ItemsSource = imgList;
}
public class ImageList
{
public string ImageName { get; set; }
}
}
This actually works smoothly and looks good too.. There are few more ways to achieve what you are trying. Do let me know if this works or not. I will suggest others if this doesn't work for u!

How to place an XAML usercontrol in a grid

I have the following main.xaml and usercontrol.
I need to place several times the user control on the 2nd row, 2nd column of the grid, By using visual studio it wont allow to drag and drop the user control, so I suppose I have to do it by code, I just dont know how
MainPage.xaml
<Grid HorizontalAlignment="Left" Height="768" VerticalAlignment="Top" Width="1366" x:Name="grid" Background="Black">
<Grid.RowDefinitions>
<RowDefinition Height="150"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="250"/>
</Grid.ColumnDefinitions>
<Border BorderBrush="White" BorderThickness="3" Grid.Column="1" Background="Red" CornerRadius="30"/>
<TextBlock x:Name="txtCountry" Grid.Column="1" TextWrapping="Wrap" FontSize="36" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<TextBlock x:Name="txtTime" Grid.Row="1" TextWrapping="Wrap" FontSize="180" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
Usercontrol
<UserControl
x:Class="AlarmPro.TimeOnCity"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:AlarmPro"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="150"
d:DesignWidth="250">
<Grid Background="Black">
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Border BorderBrush="#FFDE6A6A" BorderThickness="1" Grid.Row="0" Grid.Column="0" Background="#FFDC4646">
<TextBlock TextWrapping="Wrap" Text="TextBlock" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="16"/>
</Border>
<Border BorderBrush="Black" BorderThickness="1" Grid.Row="1" Background="#FFAE4F00">
<TextBlock TextWrapping="Wrap" Text="TextBlock" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="36"/>
</Border>
</Grid>
</UserControl>
Do you mean like this?
<my:UserControlName Grid.Column="2" Grid.Row="2" ... />
<my: in this case is the alias for the CLR namespace the UserControl resides in. It is defined at the top of your XAML, inside the <Window> or <UserControl> tag depending on context.
For example,
<Window ...
xmlns:my="clr-namespace:AssemblyName"
...
/>
MainPage.Xaml
<Page
x:Class="UserControlExample.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:UserControlExample"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid x:Name="MainContent" Background="Azure" >
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ScrollViewer Grid.Row="1" HorizontalScrollBarVisibility="Hidden"
VerticalScrollBarVisibility="Hidden">
<local:UserControl1 x:Name="MyHelloWorldUserControl" Grid.Row="1" />
</ScrollViewer>
</Grid>
</Page>
UserControl1.xaml
<UserControl
x:Class="UserControlExample.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:UserControlExample"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400">
<Grid Background="Bisque">
<StackPanel>
<StackPanel Orientation="Horizontal" Height="81">
<TextBlock Text="Your Name is" Foreground="Blue" FontSize="30" Margin="0,0,0,10"/>
<TextBox x:Name="Input" Background="White" Width="225" />
</StackPanel>
<Button Content="Click Me" Foreground="Brown" FontSize="30" Click="Button_Click"/>
<TextBlock x:Name="Output" FontSize="100"/>
</StackPanel>
</Grid>
</UserControl>
MainPage.xaml, I am binding a login UserControl
by using the namespace : xmlns:UC="clr-namespace:Test.Views" , since I have my usercontrol in Folder named "Views".
<ScrollViewer>
<UC:Login BtnLoginClick="Login_BtnLoginClick"/>
</ScrollViewer>
Login.cs
public partial class Login : UserControl {
public event EventHandler BtnLoginClick;
public Login()
{
InitializeComponent();
}
private void btnLogin_Click(object sender, RoutedEventArgs e)
{
string userName = txtUserName.Text;
string userPassword = txtUserPassword.Password.Trim();
if (userName != null && userName != string.Empty && userPassword != null && userPassword != string.Empty)
{
if (this.BtnLoginClick != null)
{
this.BtnLoginClick(this, e);
}
}
else
{
MessageBox.Show("Invalid username or password");
}
}
}
Finally, dont forgot to use the event handler in MainPage.xaml to capture the button clicked event from Login Usercontrol to do other actions.
MainPage.xaml
<UC:Login BtnLoginClick="Login_BtnLoginClick"/>
Here "BtnLoginClick" its an event Handler defined in the Login.xaml[User Control].
Create new event for this "BtnLoginClick" event as i created "Login_BtnLoginClick".
MainPage.cs
private void Login_BtnLoginClick(object sender, EventArgs e)
{
Messagebox.Show("Event captured successfully");
////Here you can add your stuffs...
}
For UWP, in UserControl.xaml, find the local namespace xmlns:local notation: xmlns:local="using:ProjectName.Folder" at the top (by convention, C# namespaces are named the same way as the folder that contains them, so folder also means namespace).
In MainPage.xaml, add a reference to this namespace. The reference prefix can be any name desired: for example, CustomPrefix, as in xmlns:CustomPrefix="using:ProjectName.Folder". Then, anywhere in MainPage.xaml, display the control by prefixing its name with <CustomPrefix:...>.
UserControl.xaml
<UserControl
xmlns:local="using:ProjectName.Folder">
MainPage.xaml
<Page
xmlns:CustomPrefix="using:ProjectName.Folder">
<CustomPrefix:UserControl />
</Page>
The project needs to be built to discard XAML errors in Visual Studio, otherwise the design view remains blank and the XAML has green squiggles.

Categories

Resources