How can I use the Design Tab in Visual Studio when designing XAML UI for a UWP App that uses Data Template in List View? - visual-studio

This is a bit of a tricky question to put succinctly but here goes. Snippets have been included to get the point across.
This problem came about whilst trying to solve another problem, to which a solution was found on SO, but which required to right-click and edit the default style of a TextBox, which I can't do because the TextBox in question is part of a DataTemplate on a databound ListView which of course has no content at design time.
Here are some snippets: I use a data template to control the content/layout of my listview like so:
<ListView x:Name="DataItemList"
ItemsSource="{x:Bind MasterMenuItem.DataObjects, Mode=OneWay}"
SelectedItem="{x:Bind SelectedItem, Mode=TwoWay}"
SelectionMode="Single"
ItemTemplate="{StaticResource DataListItemTemplate}">
</ListView>
and a data template as a page/control resource
<DataTemplate x:Key="DataListItemTemplate" x:DataType="vm:DataObjectListItem">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch">
<Grid Height="40" Margin="10 0 0 0">
<Grid.Resources>
<SolidColorBrush x:Key="brush" Color="Silver"/>
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40" />
<ColumnDefinition Width="*" MinWidth="240" />
</Grid.ColumnDefinitions>
<Border Grid.Column="0" BorderBrush="{StaticResource brush}" BorderThickness="1 1 1 1">
<FontIcon Name="Icon"
Grid.Column="0"
VerticalAlignment="Center"
FontSize="32"
Glyph="{x:Bind ListItemIcon}" />
</Border>
<Border Grid.Column="1" BorderBrush="{StaticResource brush}" BorderThickness="1 1 1 1">
<TextBlock Name="Data Object Name"
Padding="6 4 6 4"
Text="{x:Bind Name, Mode=OneWay}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
FontWeight="Bold"
TextWrapping="WrapWholeWords"/>
</Border>
</StackPanel>
</DataTemplate>
When I view my page in the Design tab of visual studio (instead of the XAML tab) I see nothing useful, unlike if, for example, I put a TextBlock in my XAML with Text="Hello" I would be able to see 'Hello' in the Design tab and crucially Right-Click on it to do certain things...
Is there a way to 'populate' the list with some dummy data, or the text box with some dummy text in order to visualize the runtime layout in the Design tab?

Related

xaml - allign one control to left, another to right, but take all width of the screen

I have something like this:
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel
Orientation="Horizontal"
Margin="2">
<Image Width="64" Height="64" Source="{Binding someIcon}"></Image>
<StackPanel Orientation="Vertical" Margin="15,1,0,1">
<TextBlock Text="{Binding someText}" FontSize="30" />
<StackPanel Orientation="Horizontal">
<TextBlock Text="Some Text"/>
<TextBlock Text="{Binding someText2}"/>
</StackPanel>
</StackPanel>
</StackPanel>
<CheckBox
Content=""
Tag="{Binding someName}"
IsChecked="{Binding checked}"
Checked="someChecked"
Unchecked="someUnchecked"/>
</DataTemplate>
</ListBox.ItemTemplate>
in the ListBox.
I need to allign StackPanel to the left and CheckBox to the right. I need to take all possible screen width and place the CheckBox just at the right edge of the screen. The screen width can change, because it's an Universal Windows App.
How can I do it?
I've tried using RelativePanel and Grid, but without success. When I use Grid with 3 columns like this:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
I get the CheckBox just after the StackPanel, not at the end of the screen.
When I however use RelativePanel I get CheckBox in place of StackPanel, even though I use RelativePanel.AlignRightWithPanel="True" in CheckBox, RelativePanel.AlignLeftWithPanel="True" in StackPanel and HorizontalAlignment="Stretch" in RelativePanel.
Do you have any ideas?
Try this
When you do HorizontalContentAlignment to stretch items will take whole ListBox width
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListView.ItemContainerStyle>
....
</ListBox>

XAML alignment in Windows 8 Store App

Not being at all familiar with XAML, I'm trying to get a very simple layout designed where the main page consists of two parts:
On the left, I want an image that will scale to fit the available height but maintain its aspect ratio.
On the right, I want a panel that will eventually contain text and controls - at the moment I just have text.
I can get the image to behave ok by using a ViewBox but I can't seem to get the right side of the screen to fill the remaining gap. See screenshot:
What I want is for the area that contains the text to stretch to the right with the text centred within it.
The relevant XAML code is:
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<StackPanel Orientation="Horizontal">
<Viewbox HorizontalAlignment="Right">
<Image Source="Assets/ABCImage.png"></Image>
</Viewbox>
<StackPanel Orientation="Vertical">
<TextBlock Text="ABC Viewer"
TextAlignment="Center"
FontSize="48"></TextBlock>
<TextBlock Text="Test application"
TextAlignment="Center"
FontSize="24"></TextBlock>
</StackPanel>
</StackPanel>
</Grid>
This is taking me far too long to figure out. Can someone please put me out of my misery?
Try this :
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Viewbox Grid.Column="0"
HorizontalAlignment="Right">
<Image Source="Assets/ABCImage.png"></Image>
</Viewbox>
<StackPanel Grid.Column="1">
<TextBlock Text="SEM Viewer"
TextAlignment="Center"
FontSize="48" />
<TextBlock Text="Test application"
TextAlignment="Center"
FontSize="24" />
</StackPanel>
</Grid>

Using Expensify Windows Phone Test Framework to trigger an ApplicationBar button

I've just started using the Expensify Windows Phone Test Framework and it seems to fit my requirements for automated testing of Windows Phone 7.1 quite well. I can get it to trigger a normal button on the screen but cannot get it to trigger either of my ApplicationBar buttons.
The XAML for this test page is ...
<phone:PhoneApplicationPage x:Class="SampleApp1.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"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:AppBarUtils="clr-namespace:AppBarUtils;assembly=AppBarUtils"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait"
Orientation="Portrait"
mc:Ignorable="d"
d:DesignWidth="480"
d:DesignHeight="768"
shell:SystemTray.IsVisible="True"
DataContext="{Binding Main, Source={StaticResource Locator}}">
<!--LayoutRoot contains the root grid where all other 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="24,24,0,12">
<TextBlock x:Name="ApplicationTitle"
Text="{Binding ApplicationTitle}"
Style="{StaticResource PhoneTextNormalStyle}" />
<TextBlock x:Name="PageTitle"
Text="{Binding PageName}"
Margin="-3,-8,0,0"
Style="{StaticResource PhoneTextTitle2Style}" />
</StackPanel>
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentGrid"
Grid.Row="1">
<StackPanel Margin="24,20,0,123" Orientation="Vertical">
<TextBlock Text="{Binding Welcome, Mode=OneWay}"
Style="{StaticResource PhoneTextNormalStyle}"
HorizontalAlignment="Center" VerticalAlignment="Center"
Margin="6,0,19,0" TextWrapping="Wrap" Width="431" />
<TextBlock Text="Enter first number"
HorizontalAlignment="Left" VerticalAlignment="Top"
Margin="6,20,0,0" TextWrapping="Wrap" />
<TextBox TextChanged="OnTextBoxTextChanged"
Text="{Binding EnteredAmount1, Mode=TwoWay, UpdateSourceTrigger=Explicit}"
x:Name="txtValue1"
HorizontalAlignment="Left" Height="72" VerticalAlignment="Top" Width="456"
TextWrapping="Wrap" InputScope="Number"/>
<TextBlock Text="Enter second number"
HorizontalAlignment="Left" VerticalAlignment="Top"
Margin="6,0,0,0" TextWrapping="Wrap" />
<TextBox TextChanged="OnTextBoxTextChanged"
Text="{Binding EnteredAmount2, Mode=TwoWay, UpdateSourceTrigger=Explicit}"
x:Name="txtValue2"
HorizontalAlignment="Left" Height="72" VerticalAlignment="Top" Width="456"
TextWrapping="Wrap" InputScope="Number"/>
<TextBlock Text="Result"
HorizontalAlignment="Left" VerticalAlignment="Top"
Margin="6,20,0,0" TextWrapping="Wrap"/>
<TextBlock Text="{Binding Total, Mode=OneWay}"
HorizontalAlignment="Left" VerticalAlignment="Top"
Margin="15,0,0,0" TextWrapping="Wrap"
Width="422" Height="45"/>
<Button x:Name="btnAdd" Command="{Binding AddCommand}" Content="Add" Margin="240,0,0,0" />
</StackPanel>
</Grid>
</Grid>
<phone:PhoneApplicationPage.ApplicationBar>
<shell:ApplicationBar IsVisible="True" IsMenuEnabled="False">
<shell:ApplicationBarIconButton x:Name="AddAppBarBtn" IconUri="/Images/ApplicationBar.Check.png" Text="add"></shell:ApplicationBarIconButton>
<shell:ApplicationBarIconButton x:Name="SubtractAppBarBtn" IconUri="/Images/ApplicationBar.Cancel.png" Text="subtract"></shell:ApplicationBarIconButton>
</shell:ApplicationBar>
</phone:PhoneApplicationPage.ApplicationBar>
<i:Interaction.Behaviors>
<AppBarUtils:AppBarItemCommand Id="add" Command="{Binding AddCommand}"/>
<AppBarUtils:AppBarItemCommand Id="subtract" Command="{Binding SubtractCommand}"/>
</i:Interaction.Behaviors>
<i:Interaction.Triggers>
<AppBarUtils:AppBarItemTrigger Type="Button" Id="add" Text="add" />
<AppBarUtils:AppBarItemTrigger Type="Button" Id="subtract" Text="subtract" />
</i:Interaction.Triggers>
</phone:PhoneApplicationPage>
The SpecFlow features are defined as follows ...
Scenario: AppBar Add Two Numbers
Given my app is uninstalled
And my app is installed
And my app is running within 20 seconds
Then I enter "34" into the control "txtValue1"
Then I enter "23" into the control "txtValue2"
Then I press the control "AddAppBarBtn"
Scenario: Button Add Two Numbers
Given my app is uninstalled
And my app is installed
And my app is running within 20 seconds
Then I enter "34" into the control "txtValue1"
Then I enter "23" into the control "txtValue2"
Then I press the control "btnAdd"
The ButtonAddTwoNumbers scenario fully works. The AppBarAddTwoNumbers fills in the text box values but refuses to press the button, The error I get is "Failed to set focus to control 'AddAppBarBtn'".
Any help on this would be appreciated.
I think you are working one level too high. Personally I wouldn't normally test the UI itself as in the long term it just leads to brittle tests that constantly need changing. Instead I would normally come down to the ViewModels.
So given that your txtValue1 is bound to EnteredAmount1, txtValue2 is EnteredAmount2 and AddAppBarBtn is AddCommand, you can test your business logic as
Scenario: AppBar Add Two Numbers
Given I enter 34 into Amount1
And I enter 23 into Amount2
When I add them #Calls AddCommand
Then Total should be 57
This means that you can redesign your UI very easily, so say for example if we wanted to use sliders instead of textboxes, there would be NO changes to the above logic tests.
In addition you can still test your UI features as seperate features
Scenario: Check startup
Given my app is uninstalled
When my app is installed
Then my app should be running within 20 seconds
And if you really want you can still check your bindings too
Scenario: Check bindings
Given I enter 34 into Amount1
Then control txtValue1 should be 34
In this way you'll break your tests into smaller chunks of the application and give yourself more targetted failures, which is really useful when tracking down any problems.

C# windows phone -Alignment in xaml ListBox.ItemTemplate

i Would like to make simple ListBox. Each line should contain 2 controls, one aligned to the left the other to the right, thats all :)
I tried multiple approaches but nothing worked. My code is following
<StackPanel Grid.Row="1" Margin="12,0,12,0" Grid.Column="0">
<ListBox Name="ListBox" Margin="12,0,12,0" ItemsSource="Exercises" HorizontalContentAlignment="Stretch">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Width=">
<TextBlock Text="abc" HorizontalAlignment="Left" VerticalAlignment="Center"/>
<TextBlock Text="def" HorizontalAlignment="Right" VerticalAlignment="Center"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
(Two textblocks are just for demonstration, in real application i'd like to bind one text block to real data, instead of second ill use button.)
When ill compile this, both textblock are aligned to the left, in emulator, it seems like one textblock with text "abcdef".
Any idea how to align one text block to the right and the other one to the left?
many thanks :)
By default the ListBoxItem does not fill the space it is given. It aligns itself and the content to the left. To ensure that the content of your ListBoxItem spans the entire width, you need to change the ItemContainerStyle
<ListBox>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
Now the content will span the available width. If you wish to use a StackPanel as in your example, make sure to set it's HorizontalAlignment also. The StackPanel also does not fill in the available space given
<DataTemplate>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch">
<TextBlock Text="abc" HorizontalAlignment="Left" VerticalAlignment="Center"/>
<TextBlock Text="def" HorizontalAlignment="Right" VerticalAlignment="Center"/>
</StackPanel>
</DataTemplate>
However, I would recommend using a Grid and defining two columns
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Text="abc" HorizontalAlignment="Left" VerticalAlignment="Center"/>
<TextBlock Text="def" Grid.Column="1" HorizontalAlignment="Right" VerticalAlignment="Center"/>
</Grid>
</DataTemplate>

Slow Page loading when using ExpanderView & Binding (Windows Phone 7)

I have a Panorama control, which has an ExpanderView Item (from Silverlight toolkit).
My client wants this page to be customizable. Thats why I created 3 level of binding:
The PanoramaItems, the ExpanderView headers and the ExpanderView content.
The problem when I set the itemssource of the Panorama control. it takes about 5 seconds to show the items.
Any idea how I can solve this?
C# code:
private void panorama_Loaded(object sender, RoutedEventArgs e)
{
this.DataContext = App.Products;
}
XAML Code:
<controls:Panorama Loaded="panorama_Loaded" x:Name="panorama" ItemsSource="{Binding}">
<controls:Panorama.ItemTemplate>
<DataTemplate>
<ListBox ItemsSource="{Binding Sub_Products}" >
<ListBox.ItemTemplate>
<DataTemplate>
<toolkit:ExpanderView Header="{Binding}" Expander="{Binding}" ItemsSource="{Binding Sub_Sub_Products}">
<toolkit:ExpanderView.ExpanderTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image VerticalAlignment="Center" Source="Images/List.png" Width="25" />
<TextBlock Text="{Binding Title}" />
</StackPanel>
</DataTemplate>
</toolkit:ExpanderView.ExpanderTemplate>
<toolkit:ExpanderView.ItemTemplate>
<DataTemplate>
<Grid Margin="-30,0,0,0" Background="White" Width="450" Tap="Grid_Tap" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Image Grid.Row="0" Source="{Binding ImageSource}" />
<StackPanel VerticalAlignment="Top" Grid.Column="1">
<TextBlock Text="{Binding Title}" />
<TextBlock Text="{Binding Description}" />
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
</Grid>
<TextBlock Margin="0,12,32,0" Grid.Row="1" Text="Learn more" />
</StackPanel>
</Grid>
</DataTemplate>
</toolkit:ExpanderView.ItemTemplate>
</toolkit:ExpanderView>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</DataTemplate>
</controls:Panorama.ItemTemplate>
</controls:Panorama>
You could try to collapse the panorama items that are off screen and only set visibility to visible on demand. That should at least reduce the size of the visible tree.
A good way to find the slow parts is to use the profiler in Visual Studio. You will find one frame which is really slow (it will have a render time of 5 seconds in your case). Then dig into the visual tree of that frame and see which elements took a long time to render and try to optimize these.
Remove the ExpanderView ItemsSource binding in xaml and bind to it when the Expander is manupulated in code. Just leave it as ItemsSource="{Binding}". That way you will dynamically build you visual tree as the user taps on the expander.
The event handler is something like below. I am assuming Product is the type in your App.Products list. Also ensure that you hook up the event in your xaml for the expander.
private void ExpanderView_ManipulationStarted(object sender, System.Windows.Input.ManipulationStartedEventArgs e)
{
var expander = sender as ExpanderView;
expander.ItemsSource = (expander.DataContext as Product).Sub_Sub_Products;
}
Hope this solves your slow loading issues and is not too late at this time.

Resources