I have a few information that i want to display inside the DockPanel but , it goes out of line in the DockPanel and some text got cut off like this :
i populate them in code behind , how do i set the dockpanel alignment such that the whole content can be placed inside it without being cut-off .
Heres the xaml code :
<Grid Background="#FF5EC136">
<DockPanel Height="894" HorizontalAlignment="Stretch" Margin="365,135,0,0" Name="dockPanel1" VerticalAlignment="Top" Width="1174" />
</Grid>
i don't know if my xaml.cs will be useful , so i just post it here most of the codes are unrelated tho :
private void PopulateQuestion(int activityID, int taskID)
{
IList<Model.questionhint> lstQuestionHints = qh.GetRecords(taskID, activityID);
StackPanel sp = new StackPanel();
foreach (Model.questionhint qhm in lstQuestionHints)
{
StackPanel sp1 = new StackPanel() { Orientation = Orientation.Horizontal };
TextBlock tb = new TextBlock();
tb.Text = qhm.QuestionContent;
tb.FontWeight = FontWeights.Bold;
tb.FontSize = 24;
sp1.Children.Add(tb);
TextBox tbox = new TextBox();
tbox.Width = 100;
tbox.FontSize = 24;
tbox.FontWeight = FontWeights.Bold;
if (qhm.Option1.Trim().Length > 0 &&
qhm.Option2.Trim().Length > 0)
{
sp1.Children.Add(tbox);
}
Label btn1 = new Label();
Label btn2 = new Label();
if (qhm.Option1.Trim().Length > 0)
{
btn1.Content = qhm.Option1;
btn1.Width = 110;
btn1.FontSize = 24;
btn1.FontWeight = FontWeights.Bold;
btn1.Foreground = (SolidColorBrush)new BrushConverter().ConvertFromString("#FFE22B2B");
sp1.Children.Add(btn1);
btn1.MouseLeftButtonDown += (source, e) =>
{
btn2.Foreground = (SolidColorBrush)new BrushConverter().ConvertFromString("#FFE22B2B");
btn1.Foreground = (SolidColorBrush)new BrushConverter().ConvertFromString("#FFF0FA08");
tbox.Text = btn1.Content.ToString();
};
}
if (qhm.Option2.Trim().Length > 0)
{
btn2.Content = qhm.Option2;
btn2.Width = 110;
btn2.FontSize = 24;
btn2.FontWeight = FontWeights.Bold;
btn2.Foreground = (SolidColorBrush)new BrushConverter().ConvertFromString("#FFE22B2B");
sp1.Children.Add(btn2);
btn2.MouseLeftButtonDown += (source, e) =>
{
btn1.Foreground = (SolidColorBrush)new BrushConverter().ConvertFromString("#FFE22B2B");
btn2.Foreground = (SolidColorBrush)new BrushConverter().ConvertFromString("#FFF0FA08");
tbox.Text =btn2.Content.ToString();
};
}
sp.Children.Add(sp1);
}
dockPanel1.Children.Add(sp);
Use WrapPanel instead of StackPanel. Replace following line in your code
StackPanel sp1 = new StackPanel() { Orientation = Orientation.Horizontal };
with
WrapPanel wp = new WrapPanel();
Related
There is a Grid, which is filled dynamically with Image controls in code behind(Sorry for that).
Grid has 1 column, many pages, each page has 1 Border with Image as Border.Child inside. What I need is to Zoom (Scale) my Image in Grid when Button.Click event fires. I used Scale Transform with the Image before, but I didn't manage to bind Grid element Image with the Click handler.
Please suggest, how I can zoom images inside grid, step by step.
Thanks in advance!
Yes, I know this is horrible, should be done in different way, I'm still learning, how to do this right.
Method, that generates Grid. After that ZOOM click method ( only for zoom, there is another method for zoom out)
public void RefreshView(List<TiffImage> tiffImageList)
{
try
{
if (tiffImageList.Count == 0)
return;
SetControlSizes();
gridImageList.Children.Clear();
gridImageList.RowDefinitions.Clear();
gridImageList.ColumnDefinitions.Clear();
RowDefinitionCollection rd = gridImageList.RowDefinitions;
ColumnDefinitionCollection cd = gridImageList.ColumnDefinitions;
cd.Add(new ColumnDefinition() { Width = GridLength.Auto });
for (int i = 0; i < tiffImageList.Count; i++)
{
rd.Add(new RowDefinition() { Height = GridLength.Auto });
}
int rowIndex = 0;
foreach (var tiffImage in tiffImageList)
{
Image imageListViewItem = new Image();
imageListViewItem.Margin = new Thickness(0, 0, 0, 0);
RenderOptions.SetBitmapScalingMode(imageListViewItem, BitmapScalingMode.HighQuality);
imageListViewItem.Name = $"Image{tiffImage.index.ToString()}";
imageListViewItem.Source = tiffImage.image;
imageListViewItem.HorizontalAlignment = HorizontalAlignment.Center;
imageListViewItem.VerticalAlignment = VerticalAlignment.Center;
imageListViewItem.Stretch = Stretch.Uniform;
imageListViewItem.VerticalAlignment = VerticalAlignment.Center;
imageListViewItem.HorizontalAlignment = HorizontalAlignment.Center;
Border border = new Border();
border.BorderBrush = Brushes.LightGray;
border.BorderThickness = new Thickness(1);
Thickness margin = border.Margin;
border.Margin = new Thickness(20, 10, 20, 10);
border.Child = imageListViewItem;
Grid.SetColumn(border, 0);
Grid.SetRow(border, rowIndex);
gridImageList.Children.Add(border);
rowIndex++;
}
}
catch (Exception ex)
{
throw ex;
}
}
private void btnZoom_Click(object sender, RoutedEventArgs e)
{
foreach (UIElement item in gridImageList.Children)
{
Border border = (Border)item;
Image image = (Image)border.Child;
var imgViewerScaleTransform = (ScaleTransform)(image.LayoutTransform);
if ((imgViewerScaleTransform.ScaleX + 0.2) > 3 || (imgViewerScaleTransform.ScaleY + 0.2) > 3)
return;
imgViewerScaleTransform.ScaleX += 0.2;
imgViewerScaleTransform.ScaleY += 0.2;
image.LayoutTransform = imgViewerScaleTransform;
}
}
Here is a very simple version of a scalable ItemsControl in a ScrollViewer.
It might be improved in many ways. First of all, you should replace handling Button Click events by binding the Button Command properties to ZoomIn and ZoomOut commands in the view model (left out for brevity).
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ScrollViewer HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto">
<ItemsControl ItemsSource="{Binding Images}">
<ItemsControl.LayoutTransform>
<ScaleTransform ScaleX="{Binding Scale}" ScaleY="{Binding Scale}"/>
</ItemsControl.LayoutTransform>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="1"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderThickness="1" BorderBrush="LightGray">
<Image Source="{Binding}"/>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
<StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Right">
<Button Content=" + " Click="ZoomInButtonClick"/>
<Button Content=" - " Click="ZoomOutButtonClick"/>
</StackPanel>
</Grid>
The code behind:
public partial class MainWindow : Window
{
private readonly ViewModel viewModel = new ViewModel();
public MainWindow()
{
InitializeComponent();
DataContext = viewModel;
foreach (string imageFile in Directory.EnumerateFiles(
#"C:\Users\Public\Pictures\Sample Pictures", "*.jpg"))
{
viewModel.Images.Add(new BitmapImage(new Uri(imageFile)));
}
}
private void ZoomInButtonClick(object sender, RoutedEventArgs e)
{
viewModel.Scale *= 1.1;
}
private void ZoomOutButtonClick(object sender, RoutedEventArgs e)
{
viewModel.Scale /= 1.1;
}
}
public class ViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public ObservableCollection<ImageSource> Images { get; }
= new ObservableCollection<ImageSource>();
private double scale = 1;
public double Scale
{
get { return scale; }
set
{
scale = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Scale)));
}
}
}
I managed to find an ugly, horrible solution, sorry for that. Use it only, if there is no any alternative. Please, add answers with better solutions. Thanks for your time!
We need to add (in code behind) Image.LayoutTransform defined as ScaleTransform:
imageListViewItem.LayoutTransform = new ScaleTransform();
I used // to emphasize changes in method below. Also, most changes happened in Zoom/ZoomOut methods below.
public void RefreshView(List<TiffImage> tiffImageList)
{
try
{
if (tiffImageList.Count == 0)
return;
SetControlSizes();
gridImageList.Children.Clear();
gridImageList.RowDefinitions.Clear();
gridImageList.ColumnDefinitions.Clear();
RowDefinitionCollection rd = gridImageList.RowDefinitions;
ColumnDefinitionCollection cd = gridImageList.ColumnDefinitions;
cd.Add(new ColumnDefinition() { Width = GridLength.Auto });
for (int i = 0; i < tiffImageList.Count; i++)
{
rd.Add(new RowDefinition() { Height = GridLength.Auto });
}
int rowIndex = 0;
foreach (var tiffImage in tiffImageList)
{
Image imageListViewItem = new Image();
imageListViewItem.Margin = new Thickness(0, 0, 0, 0);
RenderOptions.SetBitmapScalingMode(imageListViewItem, BitmapScalingMode.HighQuality);
imageListViewItem.Name = $"Image{tiffImage.index.ToString()}";
imageListViewItem.Source = tiffImage.image;
imageListViewItem.HorizontalAlignment = HorizontalAlignment.Center;
imageListViewItem.VerticalAlignment = VerticalAlignment.Center;
imageListViewItem.Stretch = Stretch.Uniform;
imageListViewItem.VerticalAlignment = VerticalAlignment.Center;
imageListViewItem.HorizontalAlignment = HorizontalAlignment.Center;
// Add HERE!!!
imageListViewItem.LayoutTransform = new ScaleTransform();
//
Border border = new Border();
border.BorderBrush = Brushes.LightGray;
border.BorderThickness = new Thickness(1);
Thickness margin = border.Margin;
border.Margin = new Thickness(20, 10, 20, 10);
border.Child = imageListViewItem;
Grid.SetColumn(border, 0);
Grid.SetRow(border, rowIndex);
gridImageList.Children.Add(border);
rowIndex++;
}
}
catch (Exception ex)
{
throw ex;
}
}
We take all elements from the Grid and Scale(Zoom) them, then we clear the Grid.Children and fill it with new Items.
private void btnZoom_Click(object sender, RoutedEventArgs e)
{
List<Border> list = new List<Border>();
foreach (UIElement item in gridImageList.Children)
{
Border border = (Border)item;
Image image = (Image)border.Child;
var imgViewerScaleTransform = (ScaleTransform)(image.LayoutTransform);
imgViewerScaleTransform.CenterX = 0.5;
imgViewerScaleTransform.CenterY = 0.5;
if ((imgViewerScaleTransform.ScaleX + 0.2) > 3 || (imgViewerScaleTransform.ScaleY + 0.2) > 3)
return;
imgViewerScaleTransform.ScaleX += 0.2;
imgViewerScaleTransform.ScaleY += 0.2;
image.LayoutTransform = imgViewerScaleTransform;
border.Child = image;
list.Add(border);
}
gridImageList.Children.Clear();
foreach (Border border in list)
{
gridImageList.Children.Add(border);
}
}
private void btnZoomOut_Click(object sender, RoutedEventArgs e)
{
List<Border> list = new List<Border>();
foreach (UIElement item in gridImageList.Children)
{
Border border = (Border)item;
Image image = (Image)border.Child;
var imgViewerScaleTransform = (ScaleTransform)(image.LayoutTransform);
imgViewerScaleTransform.CenterX = 0.5;
imgViewerScaleTransform.CenterY = 0.5;
if ((imgViewerScaleTransform.ScaleX - 0.2) < 0.8 || (imgViewerScaleTransform.ScaleY - 0.2) < 0.8)
return;
imgViewerScaleTransform.ScaleX += -0.2;
imgViewerScaleTransform.ScaleY += -0.2;
image.LayoutTransform = imgViewerScaleTransform;
border.Child = image;
list.Add(border);
}
gridImageList.Children.Clear();
foreach (Border border in list)
{
gridImageList.Children.Add(border);
}
}
I have a pointing to null error but i dont see where the problem is since everything gets initalised before used. the points where the error acures i have given a blockquote. Like always im thankfull for every help.
Button topAddBut = null;
//Button botAddBut = null;
Button loadBut = null;
Button saveBut = null;
StackPanel topSP = null;
//StackPanel botSP = null;
public MainWindow()
{
InitializeComponent();
loadBut = new Button { Content = "Load", Width = 70, Height = 23 };
Canvas.SetRight(loadBut, 160);
Canvas.SetBottom(loadBut, 24);
canvas1.Children.Add(loadBut);
saveBut = new Button { Content = "Save", Width = 70, Height = 23 };
Canvas.SetRight(saveBut, 80);
Canvas.SetBottom(saveBut, 24);
canvas1.Children.Add(saveBut);
StackPanel topSP = new StackPanel { Width = 400, Height = 50 };
Canvas.SetLeft(topSP, 160);
Canvas.SetTop(topSP, 100);
AddWrapPanelTop();
AddTextBoxTop();
AddTopButton();
}
void AddTextBoxTop()
{
TextBox txtB1 = new TextBox();
txtB1.Text = "Text";
txtB1.Width = 75;
txtB1.Height = 75;
WrapPanel wp = (WrapPanel)topSP.Children[0];
wp.Children.Add(txtB1);
}
void AddWrapPanelTop()
{
WrapPanel myWrapPanel = new WrapPanel();
SolidColorBrush mySolidColorBrush = new SolidColorBrush();
mySolidColorBrush.Color = Color.FromArgb(255, 0, 0, 255);
myWrapPanel.Background = System.Windows.Media.Brushes.Magenta;
myWrapPanel.Orientation = Orientation.Horizontal;
myWrapPanel.Width = 4000;
myWrapPanel.HorizontalAlignment = HorizontalAlignment.Left;
myWrapPanel.VerticalAlignment = VerticalAlignment.Top;
topSP.Children.Add(myWrapPanel);
}
void AddTopButton()
{
TextBox txtB1 = new TextBox();
txtB1.Background = System.Windows.Media.Brushes.Magenta;
txtB1.Text = "Text";
txtB1.Width = 75;
txtB1.Height = 75;
topAddBut = new Button();
topAddBut.Click += new RoutedEventHandler(this.TopClick);
topAddBut.Content = "Add";
topAddBut.Width = 75;
// Add the buttons to the parent WrapPanel using the Children.Add method.
WrapPanel wp = (WrapPanel)topSP.Children[0];
wp.Children.Add(txtB1);
wp.Children.Add(loadBut);
this.topSP.Children.Add(wp);
}
void TopClick(Object sender, EventArgs e)
{
TextBox txtB1 = new TextBox();
txtB1.Background = System.Windows.Media.Brushes.Magenta;
txtB1.Text = "Text";
txtB1.Width = 75;
txtB1.Height = 75;
Button s = (Button)sender;
WrapPanel wp = (WrapPanel)s.Parent;
wp.Children.Remove(s);
wp.Children.Add(txtB1);
AddTopButton();
// Add the buttons to the parent WrapPanel using the Children.Add method.
}
}
}
You define the following:
StackPanel topSP = null;
Then you have
StackPanel topSP = new StackPanel { Width = 400, Height = 50 };
This is in your local scope though so will be destroyed when you exit the function
Finally you have
topSP.Children.Add(myWrapPanel);
This will still be set to null which is why your error occurs. Basically you are creating a local version of the same variable.
In order to resolve simply change the second definition to:
topSP = new StackPanel { Width = 400, Height = 50 };
I want to expand a Wrap Panel only in width also the Wrap Panel shall not draw over another Stack Panel that already exists. The Problem is probably with the standard configuration of Buttons which i added to the wrap panel also my lack of knowledge about auto sizing, so content or guides to this topic would be appreciated. The Button i add to wrap panel shall add text boxes to it, but how i said just in the width.
Edit.: is there a way to add a visual studio projekt to a post/comment?
{
/// <summary>
/// Interaktionslogik für MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
stackPanel1.Width = Double.NaN;
stackPanel1.Height = Double.NaN;
stackPanel2.Width = Double.NaN;
stackPanel2.Height = Double.NaN;
AddWrapPanelMaster();
}
Button AddButtonSlave(Button but)
{
but.Click += new RoutedEventHandler(this.buttClickSlave);
return (but);
}
Button AddButtonMaster(Button but)
{
but.Click += new RoutedEventHandler(this.buttClickMaster);
return (but);
}
void buttClickMaster(Object sender, EventArgs e)
{
TextBox txtB1 = new TextBox();
txtB1.Text = "Text";
txtB1.Width = 75;
txtB1.Height = 75;
Button s = (Button)sender;
WrapPanel wp = (WrapPanel)s.Parent;
wp.Children.Add(txtB1);
}
void buttClickSlave(Object sender, EventArgs e)
{
Button s = (Button)sender;
if (s.Background != Brushes.Blue && s.Background != Brushes.Red && s.Background != Brushes.Green)
s.Background = Brushes.Red;
else
if (s.Background == Brushes.Green)
s.Background = Brushes.Red;
else
if (s.Background == Brushes.Blue)
s.Background = Brushes.Green;
else
if (s.Background == Brushes.Red)
s.Background = Brushes.Blue;
}
void AddTextBox(Button sender) {
TextBox txtB1 = new TextBox();
txtB1.Text = "Text";
txtB1.Width = 75;
txtB1.Height = 75;
WrapPanel s = (WrapPanel)sender.Parent;
s.Children.Add(txtB1);
// Add the buttons to the parent WrapPanel using the Children.Add method.
}
void AddWrapPanelSlave() {
WrapPanel myWrapPanel = new WrapPanel();
myWrapPanel.Background = System.Windows.Media.Brushes.Azure;
myWrapPanel.Orientation = Orientation.Horizontal;
myWrapPanel.Width = 200;
myWrapPanel.HorizontalAlignment = HorizontalAlignment.Left;
myWrapPanel.VerticalAlignment = VerticalAlignment.Top;
// Define 3 button elements. The last three buttons are sized at width
// of 75, so the forth button wraps to the next line.
Button btn1 = new Button();
btn1 = AddButtonSlave(btn1);
btn1.Content = "Button 1";
btn1.Width = 75;
Button btn2 = new Button();
btn2.Content = "Button 2";
btn2.Width = 75;
// Add the buttons to the parent WrapPanel using the Children.Add method.
myWrapPanel.Children.Add(btn1);
myWrapPanel.Children.Add(btn2);
this.stackPanel1.Children.Add(myWrapPanel);
}
void AddWrapPanelMaster()
{
WrapPanel myWrapPanel = new WrapPanel();
myWrapPanel.Background = System.Windows.Media.Brushes.Azure;
myWrapPanel.Orientation = Orientation.Horizontal;
myWrapPanel.Width = 200;
myWrapPanel.HorizontalAlignment = HorizontalAlignment.Left;
myWrapPanel.VerticalAlignment = VerticalAlignment.Top;
// Define 3 button elements. The last three buttons are sized at width
// of 75, so the forth button wraps to the next line.
TextBox txtB1 = new TextBox();
txtB1.Text = "Text";
txtB1.Width = 75;
txtB1.Height = 75;
Button btn1 = new Button();
btn1 = AddButtonMaster(btn1);
btn1.Content = "Add";
btn1.Width = 75;
// Add the buttons to the parent WrapPanel using the Children.Add method.
myWrapPanel.Children.Add(txtB1);
myWrapPanel.Children.Add(btn1);
this.stackPanel2.Children.Add(myWrapPanel);
}
private void button1_Click(object sender, RoutedEventArgs e)
{
AddWrapPanelSlave();
this.Show();
}
}
}
Answered, Thanks to Rohit Vats & Panagiotis Kanavos for their answers worked perfectly!
I want a ComboBox to go on the same line as a TextBox in a Stackpanel but it just puts it on the line below when the margins are the same.
The ComboBox and the Textboxs are being generated when I click a button.
C# Code:
int t = 0;
private void btnAddTitle_Click(object sender, RoutedEventArgs e)
{
StackPanel sp = new StackPanel() { Orientation = Orientation.Horizontal };
TextBox x = new TextBox();
x.Name = "Title" + t;
x.Text = "Title...";
x.FontWeight = FontWeights.Bold;
x.FontStyle = FontStyles.Italic;
x.TextWrapping = TextWrapping.Wrap;
x.Height = 25;
x.Width = 200;
x.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
x.VerticalAlignment = System.Windows.VerticalAlignment.Top;
x.Margin = new Thickness(0, 15, 0, 0);
ComboBox y = new ComboBox();
y.Name = "Combo" + t;
y.Text = (t + 1).ToString();
y.Height = 25;
y.Width = 45;
y.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
y.VerticalAlignment = System.Windows.VerticalAlignment.Top;
y.Margin = new Thickness(0, 15, 0, 0);
spStandard.Children.Add(x);
spStandard.Children.Add(y);
spStandard.Children.Add(sp);
t++;
}
int q = 0;
private void btnQuestion_Click(object sender, RoutedEventArgs e)
{
TextBox x = new TextBox();
x.Name = "Question" + q;
x.Text = "Question...";
x.FontStyle = FontStyles.Italic;
x.TextWrapping = TextWrapping.Wrap;
x.Height = 25;
x.Width = 500;
x.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
x.AcceptsReturn = true;
x.Margin = new Thickness(70, 15, 0, 0);
spStandard.Children.Add(x);
q++;
}
Picture of what is happening:
http://i.stack.imgur.com/F3Nk8.png
As you can see the Combobox object is getting put under the Textbox when I need it to the left of the Textbox.
Is there any way that i can get around this but by keeping the Stackpanel?
(I asked a question similar to this before but it wasn't for this exact reason.)
You should add it in a StackPanel sp with Orientation set to Horizontal instead of directly adding to outer panel.
Change
spStandard.Children.Add(x);
spStandard.Children.Add(y);
to
sp.Children.Add(x);
sp.Children.Add(y);
It looks like you are adding the elements to the wrong StackPanel. Instead of adding them to sp, which has Orientation = Orientation.Horizontal you add them to spStandard.
You should change:
spStandard.Children.Add(x);
spStandard.Children.Add(y);
to
sp.Children.Add(x);
sp.Children.Add(y);
I know there are issues with popups and orientation. I've read that if a popup is in the visual tree, it should respect the orientation. I have two types of popups, one global (not in the visual tree) and one that is defined on a specific page xaml. I haven't gotten around to dealing with the global yet, but I was hoping to get the page specific one working.
Here is my xaml:
x:Class="Views.MainPanorama"
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:controls="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"
xmlns:toolkitPrimitives="clr-namespace:Microsoft.Phone.Controls.Primitives;assembly=Microsoft.Phone.Controls.Toolkit"
mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="800"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="PortraitOrLandscape"
shell:SystemTray.IsVisible="False">
<toolkit:TransitionService.NavigationInTransition>
<toolkit:NavigationInTransition>
<toolkit:NavigationInTransition.Backward>
<toolkit:TurnstileTransition Mode="BackwardIn"/>
</toolkit:NavigationInTransition.Backward>
<toolkit:NavigationInTransition.Forward>
<toolkit:TurnstileTransition Mode="ForwardIn"/>
</toolkit:NavigationInTransition.Forward>
</toolkit:NavigationInTransition>
</toolkit:TransitionService.NavigationInTransition>
<toolkit:TransitionService.NavigationOutTransition>
<toolkit:NavigationOutTransition>
<toolkit:NavigationOutTransition.Backward>
<toolkit:TurnstileTransition Mode="BackwardOut"/>
</toolkit:NavigationOutTransition.Backward>
<toolkit:NavigationOutTransition.Forward>
<toolkit:TurnstileTransition Mode="ForwardOut"/>
</toolkit:NavigationOutTransition.Forward>
</toolkit:NavigationOutTransition>
<ScrollViewer x:Name="mainScroll">
<Grid x:Name="LayoutRoot" Style="{StaticResource BackgroundStyle}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Image x:Name="icon" Source="/Folder;component/Images/Icons/logo.png" Height="24" Width="175" HorizontalAlignment="Left" Margin="20, 15, 0, 0" />
<controls:Panorama Name="panMain" HeaderTemplate="{StaticResource PanoramaHeaderTemplate}" Grid.Row="1" Margin="0, -10, 0, 0" Height="680">
<!--Panorama definition here-->
</controls:Panorama>
<gbl:SecureFooter ShowLock="True" x:Name="panoFoot" Grid.Row="2" VerticalAlignment="Bottom" Margin="24, 24, 24, 0" />
<Popup x:Name="_popup" Grid.Row="3" />
</Grid>
</ScrollViewer>
The page works and the popup appears, but when I rotate the phone or emulator, the contents of the popup don't change orientation.
I'm setting the contents of the popup in code using:
_popup.Child = new OneOfTwoPopupUserControls();
Could this be causing the popup to ignore orientation? Does it need to have the full contents inside it when it's created in the xaml?
If you want to add the Popup to the visual tree, use the following line, the Popup rotates correctly:
LayoutRoot.Children.Add(popupInstance);
From what I understand Popup lives outside the visual tree of the Page, since the Page is what handles the Orientation changes the Popup itself is not affected.
The only solution I've worked with is listening to the orientation changed events and doing my own transform of the popup contents. Not ideal and didn't work well for me. In the end I discarded the Popup.
Sorry I couldn't be more help.
Its actually quite simple to rotate the Popup - or its content to be precise - according to orientation. All you have to do is to listen to Orientation changes ...
static PhoneApplicationFrame ApplicationRootFrame
{
get { return ((PhoneApplicationFrame) Application.Current.RootVisual); }
}
ApplicationRootFrame.OrientationChanged += OnOrientationChanged
And do something like the code below does. The TransformGroup ensures that the Popup content is rotated around the center of the content.
private static void ApplyOrientationTransform(PageOrientation orientation, FrameworkElement popupContent)
{
TransformGroup group;
switch (orientation)
{
case PageOrientation.LandscapeRight:
group = new TransformGroup();
group.Children.Add(new TranslateTransform { X = -popupContent.ActualWidth / 2, Y = -popupContent.ActualHeight / 2 });
group.Children.Add(new RotateTransform {CenterX = 0, CenterY = 0, Angle = -90});
group.Children.Add(new TranslateTransform { X = popupContent.ActualWidth / 2, Y = popupContent.ActualHeight / 2 });
popupContent.RenderTransform = group;
break;
case PageOrientation.LandscapeLeft:
group = new TransformGroup();
group.Children.Add(new TranslateTransform { X = -popupContent.ActualWidth / 2, Y = -popupContent.ActualHeight / 2 });
group.Children.Add(new RotateTransform {CenterX = 0, CenterY = 0, Angle = 90});
group.Children.Add(new TranslateTransform { X = popupContent.ActualWidth / 2, Y = popupContent.ActualHeight / 2 });
popupContent.RenderTransform = group;
break;
default:
popupContent.RenderTransform = null;
break;
}
}
I did originally try the answer as described by Oliver, but found the sizing of the popup needed changing for the information I was trying to display. I cheated a little to complete a similar issue I was having.
Initially I had all of the popup rendering calculated in the showPopup method:
private void showPopup()
{
Session session = App.getSession();
Template template = session.getTemplate();
border.BorderBrush = new SolidColorBrush(Colors.White);
border.BorderThickness = new Thickness(2);
border.Margin = new Thickness(10, 10, 10, 10);
int initialMargin ;
int landMargin ; // margin for information if displayed in landscape orientation
StackPanel stkPnlOuter = new StackPanel();
stkPnlOuter.Background = new SolidColorBrush(Colors.Black);
stkPnlOuter.Orientation = System.Windows.Controls.Orientation.Vertical;
stkPnlOuter.Tap += new EventHandler<System.Windows.Input.GestureEventArgs>(stkPnlOuter_Tap);
if (this.Orientation == PageOrientation.PortraitUp || this.Orientation == PageOrientation.PortraitDown)
{
initialMargin = 0;
landMargin = 0;
}
else
{
initialMargin = 5;
landMargin = 10;
}
TextBlock txt_blk1 = new TextBlock();
txt_blk1.Text = "Loaded Type:";
txt_blk1.TextAlignment = TextAlignment.Left;
txt_blk1.FontSize = 20;
txt_blk1.FontWeight = FontWeights.Bold;
txt_blk1.Margin = new Thickness(5, 5, 5, 5);
txt_blk1.Foreground = new SolidColorBrush(Colors.White);
TextBlock txt_blk2 = new TextBlock();
txt_blk2.Text = template.templateType == TemplateType.TYPE.TEMPLATE_FILE ? "Valido Template File" : "Valido Assessment File";
txt_blk2.TextAlignment = TextAlignment.Left;
txt_blk2.FontSize = 20;
txt_blk2.Margin = new Thickness(5,initialMargin, 5, initialMargin);
txt_blk2.Foreground = new SolidColorBrush(Colors.White);
TextBlock txt_blk3 = new TextBlock();
txt_blk3.Text = "Template Type:";
txt_blk3.TextAlignment = TextAlignment.Left;
txt_blk3.FontSize = 20;
txt_blk3.FontWeight = FontWeights.Bold;
txt_blk3.Margin = new Thickness(5, 10, 5, 5);
txt_blk3.Foreground = new SolidColorBrush(Colors.White);
TextBlock txt_blk4 = new TextBlock();
txt_blk4.Text = TemplateClassification.getName();
txt_blk4.TextAlignment = TextAlignment.Left;
txt_blk4.FontSize = 20;
txt_blk4.Margin = new Thickness(5, landMargin, 5, initialMargin);
txt_blk4.Foreground = new SolidColorBrush(Colors.White);
TextBlock txt_blk5 = new TextBlock();
txt_blk5.Text = "Client Reference:";
txt_blk5.TextAlignment = TextAlignment.Left;
txt_blk5.FontWeight = FontWeights.Bold;
txt_blk5.FontSize = 20;
txt_blk5.Margin = new Thickness(5, 10, 5, 5);
txt_blk5.Foreground = new SolidColorBrush(Colors.White);
TextBlock txt_blk6 = new TextBlock();
txt_blk6.Text = template.ClientRef == null ? "-" : template.ClientRef;
txt_blk6.TextAlignment = TextAlignment.Left;
txt_blk6.FontSize = 20;
txt_blk6.Margin = new Thickness(5, landMargin, 5, initialMargin);
txt_blk6.Foreground = new SolidColorBrush(Colors.White);
TextBlock txt_blk7 = new TextBlock();
txt_blk7.Text = "Template Code:";
txt_blk7.TextAlignment = TextAlignment.Left;
txt_blk7.FontWeight = FontWeights.Bold;
txt_blk7.FontSize = 20;
txt_blk7.Margin = new Thickness(5, 10, 5, 5);
txt_blk7.Foreground = new SolidColorBrush(Colors.White);
TextBlock txt_blk8 = new TextBlock();
txt_blk8.Text = template.Code;
txt_blk8.TextAlignment = TextAlignment.Left;
txt_blk8.FontSize = 20;
txt_blk8.Margin = new Thickness(5, landMargin, 5, initialMargin);
txt_blk8.Foreground = new SolidColorBrush(Colors.White);
TextBlock txt_blk9 = new TextBlock();
txt_blk9.Text = "Template Title:";
txt_blk9.TextAlignment = TextAlignment.Left;
txt_blk9.FontWeight = FontWeights.Bold;
txt_blk9.FontSize = 20;
txt_blk9.Margin = new Thickness(5, 10, 5, 5);
txt_blk9.Foreground = new SolidColorBrush(Colors.White);
TextBlock txt_blk10 = new TextBlock();
txt_blk10.Text = template.Title;
txt_blk10.TextAlignment = TextAlignment.Left;
txt_blk10.FontSize = 20;
txt_blk10.Margin = new Thickness(5, landMargin, 5, initialMargin);
txt_blk10.Foreground = new SolidColorBrush(Colors.White);
TextBlock txt_blk11 = new TextBlock();
txt_blk11.Text = "Modified Date:";
txt_blk11.TextAlignment = TextAlignment.Left;
txt_blk11.FontWeight = FontWeights.Bold;
txt_blk11.FontSize = 20;
txt_blk11.Margin = new Thickness(5, 10, 5, 5);
txt_blk11.Foreground = new SolidColorBrush(Colors.White);
TextBlock txt_blk12 = new TextBlock();
txt_blk12.Text = Valido_CA.modCommon.DateFromString(template.ModifiedDate);
txt_blk12.TextAlignment = TextAlignment.Left;
txt_blk12.FontSize = 20;
txt_blk12.Margin = new Thickness(5, landMargin, 5, 5);
txt_blk12.Foreground = new SolidColorBrush(Colors.White);
if (this.Orientation == PageOrientation.PortraitUp || this.Orientation == PageOrientation.PortraitDown)
{
stkPnlOuter.Children.Add(txt_blk1);
stkPnlOuter.Children.Add(txt_blk2);
stkPnlOuter.Children.Add(txt_blk3);
stkPnlOuter.Children.Add(txt_blk4);
stkPnlOuter.Children.Add(txt_blk5);
stkPnlOuter.Children.Add(txt_blk6);
stkPnlOuter.Children.Add(txt_blk7);
stkPnlOuter.Children.Add(txt_blk8);
stkPnlOuter.Children.Add(txt_blk9);
stkPnlOuter.Children.Add(txt_blk10);
stkPnlOuter.Children.Add(txt_blk11);
stkPnlOuter.Children.Add(txt_blk12);
}
else
{
StackPanel stkPnlLeft = new StackPanel();
stkPnlLeft.Orientation = System.Windows.Controls.Orientation.Vertical;
stkPnlLeft.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
StackPanel stkPnlRight = new StackPanel();
stkPnlRight.Orientation = System.Windows.Controls.Orientation.Vertical;
stkPnlRight.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
stkPnlOuter.Orientation = System.Windows.Controls.Orientation.Horizontal;
stkPnlLeft.Children.Add(txt_blk1);
stkPnlRight.Children.Add(txt_blk2);
stkPnlLeft.Children.Add(txt_blk3);
stkPnlRight.Children.Add(txt_blk4);
stkPnlLeft.Children.Add(txt_blk5);
stkPnlRight.Children.Add(txt_blk6);
stkPnlLeft.Children.Add(txt_blk7);
stkPnlRight.Children.Add(txt_blk8);
stkPnlLeft.Children.Add(txt_blk9);
stkPnlRight.Children.Add(txt_blk10);
stkPnlLeft.Children.Add(txt_blk11);
stkPnlRight.Children.Add(txt_blk12);
stkPnlOuter.Children.Add(stkPnlLeft);
stkPnlOuter.Children.Add(stkPnlRight);
}
StackPanel stkPnlInner = new StackPanel();
stkPnlInner.Orientation = System.Windows.Controls.Orientation.Horizontal;
stkPnlInner.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
Button btn_OK = new Button();
btn_OK.Content = "OK";
btn_OK.Width = 100;
btn_OK.Click += new RoutedEventHandler(btn_OK_Click);
stkPnlInner.Children.Add(btn_OK);
stkPnlInner.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
stkPnlOuter.Children.Add(stkPnlInner);
border.Child = stkPnlOuter;
if (this.Orientation == PageOrientation.PortraitUp || this.Orientation == PageOrientation.PortraitDown)
{
border.Width = 350;
border.Height = 500;
transforBorder(border);
infoPopup.Child = border;
infoPopup.IsOpen = true;
infoPopup.VerticalOffset = (this.ActualHeight - border.Height) / 2;
infoPopup.HorizontalOffset = (this.ActualWidth - border.Width) / 2;
}
else
{
border.Width = 600;
border.Height = 350;
transforBorder(border);
infoPopup.Child = border;
infoPopup.IsOpen = true;
infoPopup.HorizontalOffset = (this.ActualHeight - border.Width) / 2;
infoPopup.VerticalOffset = (this.ActualWidth - border.Height) / 2;
}
}
then in the OrientationChanged method I used the infoPopup.IsOpen = false, then called the showPopup method again.
Possibly a slightly sloppy way of doing this, but because I needed to change the width and height of the border I found this a simple was to complete the task.