ItemsControl same sized Items - c#

this is my first post here, so be tolerant for any possible mistakes I made here ;)
I am building an App where I want to have a tab Layout. So I am currently using this code:
<Grid Margin="0,97,0,0" Height="50" VerticalAlignment="Top">
<ItemsControl Margin="0,0,0,0" x:Name="itemsControl" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding name}" IsDoubleTapEnabled="False" IsHoldingEnabled="False" IsRightTapEnabled="False" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
<FlipView x:Name="flipView" Margin="0,147,0,0" ItemsSource="{Binding groups}">
<FlipView.ItemTemplate>
<DataTemplate>
<ListView ItemsSource="{Binding articles}">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<TextBlock Text="{Binding category}"/>
<TextBlock Text="{Binding title}"/>
<Image Source="{Binding image}"></Image>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</DataTemplate>
</FlipView.ItemTemplate>
</FlipView>
I would like the Items to fill the width of the ItemsControl and be equally sized.
Thank You.
Luca
Edit:
Just to better explain what I want to archieve:
I want tabs looking like the "365 Steps", "News", "Event", "Archiv" tabs in the Picture

You can use Pivot to achive something like this:
In order to do this you can use this code:
<Grid x:Name="grid">
<Grid VerticalAlignment="Top" HorizontalAlignment="Stretch" Height="100">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid Grid.Column="0" x:Name="item1" Background="DarkBlue" Tapped="item1_Tapped"/>
<Grid Grid.Column="1" x:Name="item2" Background="Orange" Tapped="item2_Tapped"/>
<Grid Grid.Column="2" x:Name="item3" Background="DarkGray" Tapped="item3_Tapped"/>
</Grid>
<Pivot x:Name="rootPivot" IsHitTestVisible="False" Margin="0,52,0,0">
<PivotItem Margin="0">
<TextBlock Text="Content of pivot item 1."/>
</PivotItem>
<PivotItem Margin="0">
<TextBlock Text="Content of pivot item 2."/>
</PivotItem>
<PivotItem Margin="0">
<Grid Background="LightGray">
<TextBlock Text="Content of pivot item 3."/>
</Grid>
</PivotItem>
</Pivot>
</Grid>
item_Tapped() event handler:
private void item3_Tapped( object sender, TappedRoutedEventArgs e )
{
rootPivot.SelectedIndex = 2;
}

Take a look at a complete example on how to do this here: https://blog.hompus.nl/2015/09/04/responsive-pivot-headers-in-universal-windows-platform-apps/
Import parts are
<Setter Target="HeaderClipper.HorizontalContentAlignment" Value="Center" />
Setting the HorizontalContentAllignment to get the centering
Taking care of the incorrect default height of a pivot header! The
default template has 48 set as height and that would not be enough in
most cases!

The other answers with using Pivot are probably the direction you might go. If you wanted to play around a bit you could create your own, but you might sacrifice some ability to have what the Pivot offers you automatically.
I totally threw this together in like 5 minutes to demonstrate how you can create your own UI for what you want. I did not put in anything like bindings, optimize how the menu would use a single property and converter detect which highlight to show, etc.
XAML
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid Grid.Column="0" Tapped="OnTapped" Tag="0">
<TextBlock Text="365 Steps" HorizontalAlignment="Center" Margin="0,0,0,6"/>
<Rectangle Fill="Red" Height="5" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Name="R0"/>
</Grid>
<Grid Grid.Column="1" Tapped="OnTapped" Tag="1">
<TextBlock Text="News" HorizontalAlignment="Center" Margin="0,0,0,6"/>
<Rectangle Fill="Red" Height="5" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Name="R1" Visibility="Collapsed"/>
</Grid>
<Grid Grid.Column="2" Tapped="OnTapped" Tag="2">
<TextBlock Text="Event" HorizontalAlignment="Center" Margin="0,0,0,6"/>
<Rectangle Fill="Red" Height="5" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Name="R2" Visibility="Collapsed"/>
</Grid>
<Grid Grid.Column="3" Tapped="OnTapped" Tag="3">
<TextBlock Text="Archive" HorizontalAlignment="Center" Margin="0,0,0,6"/>
<Rectangle Fill="Red" Height="5" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Name="R3" Visibility="Collapsed"/>
</Grid>
</Grid>
<ListView Grid.Row="1" Name="MyList">
<ListBoxItem>Foo</ListBoxItem>
<ListBoxItem>Bar</ListBoxItem>
</ListView>
</Grid>
Code
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
R0.Visibility = Visibility.Visible;
R1.Visibility = Visibility.Collapsed;
R2.Visibility = Visibility.Collapsed;
R3.Visibility = Visibility.Collapsed;
}
private void OnTapped(object sender, TappedRoutedEventArgs e)
{
var grid = sender as Grid;
string tag = grid.Tag as string;
// do more stuff depending on tag
switch (int.Parse(tag))
{
case 0:
R0.Visibility = Visibility;
R1.Visibility = Visibility.Collapsed;
R2.Visibility = Visibility.Collapsed;
R3.Visibility = Visibility.Collapsed;
MyList.DataContext = null; // todo: SET TO YOUR DATA MODEL
break;
case 1:
R1.Visibility = Visibility;
R0.Visibility = Visibility.Collapsed;
R2.Visibility = Visibility.Collapsed;
R3.Visibility = Visibility.Collapsed;
break;
}
}
}
This is not meant as a complete solution, just a jump start on and idea you can inspire from. Depends on your project, intended audience, and many other factors for what design is best for your case.

Related

WPF position elements depending on window size

I am currently working on an app to retrieve data from an SQL database and present it in the UI. I got the whole functionality runnig smoothly but now I'm stuck at der GUI part. I want the UI to adjust to the window size. The elements (img, labels, textboxes) have a minheight and minwidth but can also grow to the maximum available space. If the window gets too small, I want the UI to adjust like a responsive website.
The maximized window would like something like this:
Maximized window
The window width got to small & the elements adjust accordingly:
smaller window
My best approach was:
<Grid DataContext="{Binding CurrentPerson}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="5*"/>
</Grid.ColumnDefinitions>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Image Grid.Row="0" Source="{Binding Person.Photo}"/>
</Grid>
<Viewbox Grid.Column="1" StretchDirection="Both" Stretch="Uniform" HorizontalAlignment="Left" VerticalAlignment="Top">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Label Grid.Column="0" Grid.Row="0" VerticalAlignment="Center">Title:</Label>
<Label Grid.Column="0" Grid.Row="1" VerticalAlignment="Center">Name:</Label>
<Label Grid.Column="0" Grid.Row="2" VerticalAlignment="Center">Street:</Label>
<Label Grid.Column="0" Grid.Row="3" VerticalAlignment="Center">City:</Label>
<Label Grid.Column="0" Grid.Row="4" VerticalAlignment="Center">Number:</Label>
<TextBox Grid.Column="1" Grid.Row="0" HorizontalAlignment="Left" IsReadOnly="True" MinWidth="80"Text="{Binding Person.Title}"/>
<TextBox Grid.Column="1" Grid.Row="1" HorizontalAlignment="Left" IsReadOnly="True" MinWidth="300">
<TextBox.Text>
<MultiBinding StringFormat="{}{0} {1}">
<Binding Path="Person.LastName"/>
<Binding Path="Person.FirstName"/>
</MultiBinding>
</TextBox.Text>
</TextBox>
<TextBox Grid.Column="1" Grid.Row="2" HorizontalAlignment="Left" IsReadOnly="True" MinWidth="300" Text="{Binding Person.Street}"/>
<TextBox Grid.Column="1" Grid.Row="3" HorizontalAlignment="Left" IsReadOnly="True" MinWidth="300" Text="{Binding Person.City}"/>
<TextBox Grid.Column="1" Grid.Row="4" HorizontalAlignment="Left" IsReadOnly="True" MinWidth="30" Text="{Binding Person.Number}"/>
</Grid>
</Viewbox>
</Grid>
The problem with this solution is that when the window gets too small, the content just shrinks to fit inside the window and isn't readable anymore. If the image could move above the person data it would save a lot of space an the person data could be readable.
I played around with wrappanel, viewbox, grid, uniformgrid and so on but I couldn't get it to work the way I want it to.
Any help is very much appreciated.
Thanks in advance!
This is going to involve some kind of C# code. You could write triggers that change Grid.Row and Grid.Column values on controls and use a value converter to decide when, and but this is simpler.
First, break down your main grid into two separate grids. You've got two panes, here, basically, so get their content in separate grids.
<StackPanel x:Name="MainLayout" Orientation="Horizontal">
<Grid>
<!-- img -->
</Grid>
<Grid>
<Viewbox Stretch="Uniform">
<!-- Title, name, etc. -->
</Viewbox>
</Grid>
</StackPanel>
Give the Window a SizeChanged handler:
private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
{
if (ActualWidth < 400)
{
MainLayout.Orientation = Orientation.Vertical;
}
else
{
MainLayout.Orientation = Orientation.Horizontal;
}
}
Update
This can also be done with a UniformGrid, if you prefer.
<UniformGrid x:Name="MainLayout" Columns="2">
<Grid
HorizontalAlignment="Left"
VerticalAlignment="Top"
>
<!-- img -->
</Grid>
<Viewbox
Stretch="Uniform"
HorizontalAlignment="Left"
>
<!-- Title, name, etc. -->
</Viewbox>
</UniformGrid>
Code behind
private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
{
if (ActualWidth < 400)
{
//MainLayout.Orientation = Orientation.Vertical;
MainLayout.Columns = 1;
}
else
{
//MainLayout.Orientation = Orientation.Horizontal;
MainLayout.Columns = 2;
}
}
Update 2
You can also switch grid column and row on the right pane:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid
HorizontalAlignment="Left"
VerticalAlignment="Top"
>
<!-- Img -->
</Grid>
<Viewbox
x:Name="RightPane"
Grid.Column="1"
Grid.Row="0"
Stretch="Uniform"
HorizontalAlignment="Left">
<StackPanel
Orientation="Vertical"
>
<!-- Title, name, etc. -->
</StackPanel>
</Viewbox>
</Grid>
Code behind:
private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
{
if (ActualWidth < 400)
{
//MainLayout.Orientation = Orientation.Vertical;
//MainLayout.Columns = 1;
Grid.SetColumn(RightPane, 0);
Grid.SetRow(RightPane, 1);
}
else
{
//MainLayout.Orientation = Orientation.Horizontal;
//MainLayout.Columns = 2;
Grid.SetColumn(RightPane, 1);
Grid.SetRow(RightPane, 0);
}
}
I'd like to urge you to consider not using the Viewbox. Scaling fonts and controls to the window is unusual and not generally considered very usable. But it's your project.
If you do want to use the Viewbox, read up about its Stretch property, which governs how it scales its contents.
Have a look at ViewBox.StretchDirection as well.
As a variation to the answer by Ed you can use a value converter to check that the width of the image is now less than the minimal size you want to apply to it. So you end up with something similar to a breakpoint concept in responsive web design.
This blog article explains this:
https://www.iambacon.co.uk/blog/a-pattern-for-responsive-applications-in-wpf
This can be especially useful if you have many windows in the application that need this functionality so you can reuse the value converter across all of them.
In the simpler case that the image size is fixed and doesn't need to adjust with the window size you can use simply use a WrapPanel like this:
<WrapPanel DataContext="{Binding CurrentPerson}">
<Border BorderBrush="Black" BorderThickness="1">
<Image Grid.Row="0" Width="200" Height="200" />
</Border>
<Grid VerticalAlignment="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Label Grid.Column="0" Grid.Row="0" VerticalAlignment="Center">Title:</Label>
<Label Grid.Column="0" Grid.Row="1" VerticalAlignment="Center">Name:</Label>
<Label Grid.Column="0" Grid.Row="2" VerticalAlignment="Center">Street:</Label>
<Label Grid.Column="0" Grid.Row="3" VerticalAlignment="Center">City:</Label>
<Label Grid.Column="0" Grid.Row="4" VerticalAlignment="Center">Number:</Label>
<TextBox Grid.Column="1" Grid.Row="0" HorizontalAlignment="Left" IsReadOnly="True" MinWidth="80" Text="{Binding Person.Title}"/>
<TextBox Grid.Column="1" Grid.Row="1" HorizontalAlignment="Left" IsReadOnly="True" MinWidth="300">
<TextBox.Text>
<MultiBinding StringFormat="{}{0} {1}">
<Binding Path="Person.LastName"/>
<Binding Path="Person.FirstName"/>
</MultiBinding>
</TextBox.Text>
</TextBox>
<TextBox Grid.Column="1" Grid.Row="2" HorizontalAlignment="Left" IsReadOnly="True" MinWidth="300" Text="{Binding Person.Street}"/>
<TextBox Grid.Column="1" Grid.Row="3" HorizontalAlignment="Left" IsReadOnly="True" MinWidth="300" Text="{Binding Person.City}"/>
<TextBox Grid.Column="1" Grid.Row="4" HorizontalAlignment="Left" IsReadOnly="True" MinWidth="30" Text="{Binding Person.Number}"/>
</Grid>
</WrapPanel>

Create Listbox.ItemTemplate for each item XAML C#

I have a problem. I have listbox.ItemTemplate with Grid inside.
<ListBox x:Name="listBox" Foreground="Black" FontSize="23" Height="470">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Margin="0,0,0,40" Height="80">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="60"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock x:Name="stopName_TextBlock" Grid.Column="1" Text="{Binding Title}" Foreground="Black" FontSize="23"/>
<TextBlock x:Name="time_TextBlock" Grid.Column="2" Text="{Binding Time}" Foreground="Black" FontSize="23"/>
<Grid x:Name="firstGraphic" Visibility="Collapsed" Grid.Column="0">
<Rectangle Grid.Row="1" Height="40" Fill="#2575B0" Width="10" VerticalAlignment="Bottom"/>
<Ellipse Grid.Row="1" Fill="#2575B0" Height="20" Width="20"/>
</Grid>
<Grid x:Name="midleGraphic" Visibility="Collapsed" Grid.Column="0">
<Rectangle Height="80" Width="10" Fill="#2575B0"/>
<Rectangle Height="10" Width="30" Fill="#2575B0" HorizontalAlignment="Right" RadiusX="5" RadiusY="5"/>
</Grid>
<Grid x:Name="lastGraphic" Visibility="Collapsed" Grid.Column="0">
<Rectangle Grid.Row="2" Height="40" Fill="#2575B0" Width="10" VerticalAlignment="Top"/>
<Ellipse Grid.Row="2" Height="20" Width="20" Fill="#2575B0"/>
</Grid>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
My listbox will have 20-25 items. First item will have firstGrahic Grid. Last item - lastGraphic Grid. And the others - midleGraphic Grid. I created all this Grids, but a dont know how I can find this Grids in C# code. I want change Visability property for them.
for (int i = 0; i < mainList.Count; i++)
{
listBox.Items.Add(mainList[i]);
if (i == 0)
{
Grid grid = (Grid)this.listBox.FindName("firstGraphic");
grid.Visibility = System.Windows.Visibility.Visible;
}
}
This example with first Item, but object grid = null.
Please help me.
As I can see your model contains properties Title and Time which are bound to TextBlocks. You can also add new propery to the model, for example:
public Visibility FirstGraphicVisibility { get; set; }
and bind it to the Grid Visibility, eg:
<Grid x:Name="firstGraphic" Visibility="{Binding FirstGraphicVisibility}" Grid.Column="0">
next just change FirstGraphicVisibility propery in your source list mainList and set ItemsSource of ListBox:
ListBox.ItemsSource = mainList;

What kind of dynamic container and internal containers should I use for this intended view?

I want to make a popup which has a person's details on it. Each detail will be stacked vertically in the popup. I have two questions.
(1) How should I deal (graphically) with details which are not available?
(2) How to make the container around all the details dynamic so that its height is determined by the number of details available.
My first thought was the following;
<StackPanel Width="400"
Height="500">
<StackPanel x:Name="sp">
<Grid x:Name="spTelephone" Height="50">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50" />
<ColumnDefinition Width="200" />
<ColumnDefinition Width="50" />
<ColumnDefinition Width="50" />
</Grid.ColumnDefinitions>
<Grid Grid.Column="0">
<Ellipse Fill="Blue"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"/>
</Grid>
<Grid Grid.Column="1"
Margin="5,0,0,0">
<TextBlock Text="+Some Phone No."
VerticalAlignment="Center"
FontFamily="Verdana"/>
</Grid>
<Grid Grid.Column="2">
<Ellipse Fill="Blue"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"/>
</Grid>
<Grid Grid.Column="3">
<Ellipse Fill="Blue"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"/>
</Grid>
</Grid>
<Grid x:Name="spMobile" Height="50">
<!-- Repeat of above -->
</Grid>
<Grid x:Name="spEmail" Height="50">
<!-- Repeat of above -->
</Grid>
<!-- Further Grids -->
</StackPanel>
</StackPanel>
The idea being that if a detail is not available then I would set the Visibility property of the GRID to Visibility.Collapsed.
For example see my image with 3 details.
Then if a cell phone is not available it would look like this.
So how should I do this? I could for imagine using a ListView as well maybe as this would then take away the need to collapse the views. I could add each detail to an Item. But then how do I get the list view and its parent to resize its height?
Define datatemplate for item and use any items control to represent them.
Simple solution would be something like this:
Template
<DataTemplate x:Key="MyItemTemplate">
<Grid x:Name="spTelephone" Height="50">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50" />
<ColumnDefinition Width="200" />
<ColumnDefinition Width="50" />
<ColumnDefinition Width="50" />
</Grid.ColumnDefinitions>
<Grid Grid.Column="0">
<Ellipse Fill="Blue"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"/>
</Grid>
<Grid Grid.Column="1"
Margin="5,0,0,0">
<TextBlock Text="+Some Phone No."
VerticalAlignment="Center"
FontFamily="Verdana"/>
</Grid>
<Grid Grid.Column="2">
<Ellipse Fill="Blue"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"/>
</Grid>
<Grid Grid.Column="3">
<Ellipse Fill="Blue"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"/>
</Grid>
</Grid>
</DataTemplate>
Control
<Border BorderBrush="Black" BorderThickness="2" VerticalAlignment="Center" HorizontalAlignment="Center">
<ItemsControl ItemsSource="{Binding ItemsCollection}"
ItemTemplate="{StaticResource MyItemTemplate}"/>
</Border>
Of course you must fill collection from dataContext and for Text="+Some Phone No." also use data binding from current collection item.(Use DataContext={Binding} in template)
Border here is just to show that ItemsControl size changes according to collection-items count. Also ItemsControl can be replaced with any of it's descendants.

XAML ContentControl Data Binding is not working

I have an issue with DataTemplates en ContentControl. My case is very specific.
XAML page:
<Page
x:Class="Questionnaires.QuestionPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Questionnaires"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:selectors="using:Questionnaires.TemplateSelectors"
xmlns:interop="using:Windows.UI.Xaml.Interop"
mc:Ignorable="d">
<Page.Resources>
<!-- TODO: Delete this line if the key AppName is declared in App.xaml -->
<selectors:QuestionTypeItemTemplateSelector x:Key="QuestionTypeSelector" />
<selectors:AnswerTypeItemTemplateSelector x:Key="AnswerTypeSelector"/>
<DataTemplate x:Key="SingleSelectQuestionItemTemplate">
<Grid Margin="10">
<RadioButton HorizontalAlignment="Left" VerticalAlignment="Center"
IsChecked="{Binding IsChecked, Mode=TwoWay}"
Width="600" Height="Auto" GroupName="groupName">
<RadioButton.Content>
<TextBlock Text="{Binding Text}" TextWrapping="Wrap"/>
</RadioButton.Content>
</RadioButton>
</Grid>
</DataTemplate>
<DataTemplate x:Key="FreeQuestionItemTemplate">
<Grid Margin="10">
<ContentPresenter Content="{Binding}" ContentTemplateSelector="{StaticResource AnswerTypeSelector}" />
<!--
<GridView ItemsSource="{Binding}" SelectionMode="None">
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<WrapGrid Orientation="Horizontal" />
</ItemsPanelTemplate>
</GridView.ItemsPanel>
</GridView>
-->
</Grid>
</DataTemplate>
<DataTemplate x:Key="MultiSelectQuestionItemTemplate">
<Grid Margin="10">
<CheckBox HorizontalAlignment="Left" VerticalAlignment="Center"
IsChecked="{Binding IsChecked, Mode=TwoWay}" Width="600">
<CheckBox.Content>
<TextBlock Text="{Binding Text}" TextWrapping="Wrap"/>
</CheckBox.Content>
</CheckBox>
</Grid>
</DataTemplate>
<DataTemplate x:Key="LabelAnswerItemTemplate">
</DataTemplate>
<DataTemplate x:Key="TextAreaAnswerItemTemplate">
</DataTemplate>
<DataTemplate x:Key="TextFieldAnswerItemTemplate">
</DataTemplate>
<DataTemplate x:Key="DateAnswerItemTemplate">
</DataTemplate>
<DataTemplate x:Key="SliderAnswerItemTemplate">
<Grid Margin="10">
<Slider Width="600" Minimum="0" Maximum="100" Value="25" />
</Grid>
</DataTemplate>
</Page.Resources>
<Grid>
<Grid.Background>
<ImageBrush Stretch="None" ImageSource="Assets/IS_Bol_White.png"/>
</Grid.Background>
<Grid.ChildrenTransitions>
<TransitionCollection>
<EntranceThemeTransition/>
</TransitionCollection>
</Grid.ChildrenTransitions>
<Grid.RowDefinitions>
<RowDefinition Height="100"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="108*"/>
<RowDefinition Height="60"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="120"/>
<ColumnDefinition Width="235*"/>
<ColumnDefinition Width="1011*"/>
</Grid.ColumnDefinitions>
<TextBlock x:Name="pageTitle" Text="{Binding Path=Assignment.Definition.Name}" Style="{StaticResource HeaderTextBlockStyle}" Grid.Column="1"
IsHitTestVisible="false" TextWrapping="NoWrap" VerticalAlignment="Bottom" Margin="0,0,30,40" Grid.ColumnSpan="2" FontSize="48"/>
<Image Grid.Column="2" Grid.Row="0" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,0,30,0" Width="252" Height="71" Source="ms-appx:///Assets\innovationstudio.png" />
<Grid Grid.Column="2" Grid.Row="1" Margin="3,0,358,0" Width="650">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ProgressBar Grid.Row ="0" Maximum="1" Value="{Binding Progress}" IsIndeterminate="False" Grid.ColumnSpan="2" Foreground="Black"/>
<TextBlock Grid.Row="1" Grid.ColumnSpan="2" Margin="10 20" TextAlignment="Left" HorizontalAlignment="Left" Style="{StaticResource SubheaderTextBlockStyle}"
Text="{Binding CurrentQuestion.Text}" />
</Grid>
<GridView Grid.Column="2" Grid.Row="2" ItemsSource="{Binding CurrentQuestion.PossibleAnswers}"
ItemTemplateSelector="{StaticResource QuestionTypeSelector}" SelectionMode="None">
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<WrapGrid Orientation="Horizontal" />
</ItemsPanelTemplate>
</GridView.ItemsPanel>
</GridView>
<Grid Grid.Column="2" Grid.Row="3" Margin="3,0,358,0" Width="650">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Button x:Name="btn_Previous" Grid.Column="0" HorizontalAlignment="Left" Content="Vorige" Height="59" Width="175" IsEnabled="{Binding IsPreviousButtonEnabled}" Click="btnPrevious_Click"/>
<Button x:Name="btn_Next" Grid.Column="1" HorizontalAlignment="Right" Content="Volgende" Height="59" Width="175" IsEnabled="{Binding IsNextButtonEnabled}" Click="btnNext_Click"/>
</Grid>
</Grid>
</Page>
I use an ItemTemplateSelector to specify which type of Question it's going to be. The QuestionType is definded in the PossibleAnswer object. My ItemTemplateSelector looks like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Questionnaires.Models;
using Questionnaires.ViewModels;
namespace Questionnaires.TemplateSelectors
{
public class QuestionTypeItemTemplateSelector : DataTemplateSelector
{
protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
{
switch (((PossibleAnswer)(item)).QuestionType)
{
case "FREE":
return
((Page) ((Frame) Window.Current.Content).Content).Resources["FreeQuestionItemTemplate"]
as
Windows.UI.Xaml.DataTemplate;
case "SINGLE_SELECT":
return
((Page) ((Frame) Window.Current.Content).Content).Resources["SingleSelectQuestionItemTemplate"]
as
Windows.UI.Xaml.DataTemplate;
case "MULTI_SELECT":
return
((Page) ((Frame) Window.Current.Content).Content).Resources["MultiSelectQuestionItemTemplate"]
as Windows.UI.Xaml.DataTemplate;
case "DROPDOWN":
return
((Page) ((Frame) Window.Current.Content).Content).Resources["DropdownQuestionItemTemplate"]
as Windows.UI.Xaml.DataTemplate;
default:
return null;
}
}
}
}
This way I specify which datatemplate needs to be shown on my page. I'm currently working on the FREE questions, so i'm talking specifically about one template now. The template on my xaml looks like this:
<Page.Resources>
<!-- TODO: Delete this line if the key AppName is declared in App.xaml -->
<selectors:QuestionTypeItemTemplateSelector x:Key="QuestionTypeSelector" />
<selectors:AnswerTypeItemTemplateSelector x:Key="AnswerTypeSelector"/>
<DataTemplate x:Key="FreeQuestionItemTemplate">
<Grid Margin="10">
<ContentControl Content="{Binding}" ContentTemplateSelector="{StaticResource AnswerTypeSelector}" />
</Grid>
</DataTemplate>
<DataTemplate x:Key="SliderAnswerItemTemplate">
<Grid Margin="10">
<Slider Width="600" Minimum="0" Maximum="100" Value="25" />
</Grid>
</DataTemplate>
</Page.Resources>
To make things a little clearer: there is a difference between QuestionType and PossibleAnswerType.
QuestionType can be :
FREE
SINGLE_SELECT
MULTI_SELECT
DROPDOWN
TABLE
PossibleAnswerType can be :
LABEL
TEXT_AREA
TEXT_FIELD
DATE
SLIDER
I try to get the PossibleAnswerType of my PossibleAnswer in the FreeQuestionTemplate.
I'm using the ContentControl to do this, but the binding of my PossibleAnswer doesn't seem to work.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Questionnaires.Models;
namespace Questionnaires.TemplateSelectors
{
public class AnswerTypeItemTemplateSelector : DataTemplateSelector
{
protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
{
switch (((PossibleAnswer) (item)).PossibleAnswerType)
{
case "LABEL":
return
((Page)((Frame)Window.Current.Content).Content).Resources["LabelAnswerItemTemplate"]
as
Windows.UI.Xaml.DataTemplate;
case "TEXT_AREA":
return
((Page)((Frame)Window.Current.Content).Content).Resources["TextAreaAnswerItemTemplate"]
as
Windows.UI.Xaml.DataTemplate;
case "TEXT_FIELD":
return
((Page)((Frame)Window.Current.Content).Content).Resources["TextFieldAnswerItemTemplate"]
as
Windows.UI.Xaml.DataTemplate;
case "DATE":
return
((Page)((Frame)Window.Current.Content).Content).Resources["DateAnswerItemTemplate"]
as
Windows.UI.Xaml.DataTemplate;
case "SLIDER":
return
((Page)((Frame)Window.Current.Content).Content).Resources["SliderAnswerItemTemplate"]
as
Windows.UI.Xaml.DataTemplate;
default:
return null;
}
}
}
}
In my AnswerTypeItemTemplateSelector, the item object is always null. Anyone got me some suggestions on how to do this?
Kind regards!
Ok, looking over your new code, I think that I've worked out what your problem is. Your AnswerTypeItemTemplateSelector is used in your FreeQuestionItemTemplate DataTemplate, which is used in your QuestionTypeItemTemplateSelector. Unless you've left out some XAML, it seems as though you aren't using your QuestionTypeItemTemplateSelector anywhere, so none of this is 'plugged in'.
UPDATE >>>
In order for any Binding to work, you must set the DataContext of your Page to some meaningful value. The DataContext tells the elements in the UI where to look for its data bound values. Without setting a DataContext, the UI elements will have no access to any data (unless some has been declared in XAML, but let's not confuse matters with this). Please take a look at the DataContext in WPF article on CodeProject for more information.

Need to disable Ui when popup is open

In my Windows Store app (c#) i have Popup:
<Popup x:Name="LoginPopup" HorizontalAlignment="Center" VerticalAlignment="Center" Width="400" Height="300" IsOpen="{Binding Path=LoginPopupIsOpen}">
<Popup.ChildTransitions>
<TransitionCollection>
<PopupThemeTransition />
</TransitionCollection>
</Popup.ChildTransitions>
</Popup>
And when Popup IsOpen I need handle events only on Popup and freeze all another UI (including AppBar). It is possible without creating full screen popup with little work area?
You can do it in the xaml.cs file by using two properties.
In the event handler for the popup you are creating you can include the following two lines
this.IsEnabled = false;
this.ApplicationBar.IsVisible = false;
in the event handler where you want to close the popup, you can revert the properties back to their original values.
this.IsEnabled = true;
this.ApplicationBar.IsVisible = true;
I was also facing similar problem and used this to handle that.
private void AlertMessage_Opened(object sender, object e)
{
UIBlock.Visibility = Windows.UI.Xaml.Visibility.Visible;
}
private void AlertMessage_Closed(object sender, object e)
{
UIBlock.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
}
My popup name was AlertMessage and I attack opened and closed events with it and place a border in xaml which covers whole screen, and handle is visibility through these events.
<Border Name="UIBlock" Grid.Row="0" Grid.RowSpan="3" Background="#AAFFFFFF" Visibility="Collapsed">
</Border>
And remember to place this border before popup
I have made small popup using below code.Please try this.
<Grid Background="Black" Opacity="0.7" Visibility="Collapsed" x:Name="gdalert" Height="{Binding Height, ElementName=gdfullpage}" Width="{Binding Width, ElementName=gdfullpage}">
<Popup x:Name="settingpopup" Width="350" Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center">
<Border x:Name="settingbdrmain" Grid.Row="1" BorderThickness="0" Width="350" CornerRadius="15" >
<Grid x:Name="gdsubshape" Margin="0,10,0,10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Margin="0,0,0,0" Grid.Row="0" x:Name="dddf" FontSize="20" Text="" HorizontalAlignment="Center" TextAlignment="Center" FontFamily="Arial" FontWeight="Bold" TextWrapping="Wrap" ></TextBlock>
<TextBlock x:Name="txtsettingalert" Text="" FontSize="20" TextAlignment="Center" Width="300" FontFamily="Arial" TextWrapping="Wrap" Foreground="Black" Grid.Row="1" ></TextBlock>
<Border x:Name="settingbdr" Width="350" Grid.Row="2" Height="1" Background="Red" BorderBrush="Black" >
</Border>
<Grid x:Name="btnpanel" Grid.Row="3" Height="60">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="Auto">/ColumnDefinition>
</Grid.ColumnDefinitions>
<Button x:Name="settingok" Grid.Column="0" Height="50" HorizontalAlignment="Left"VerticalAlignment="Center" MinHeight="20" Width="170" Content="OK" FontSize="24" Foreground="Green" ></Button>
<Border x:Name="settingsubbdr" Grid.Column="1" BorderBrush="Green" Height="Auto" Width="1" ></Border>
<Button x:Name="sl" Grid.Column="2" Height="50" HorizontalAlignment="Right" VerticalAlignment="Center" MinHeight="20" Width="170" Content="Cancel" FontSize="24" Foreground="Green" ></Button>
</Grid>
</Grid>
</Border>
</Popup>
To Open Use :- popname.IsOpen = true; gdalert.Visibility = Visibility.Visible;
To Close popname.IsOpen = false; gdalert.Visibility = Visibility.Collapse;

Categories

Resources