WP7 usercontrol - change control width when orientation changes - xaml

In one of my apps I have a usercontrol called FeedControl (yep, it's yet another RSS reader!) which is very simple - just a checkbox to select the item, a textblock to show the feed name and another textblock to show the number of unread feed items. On loading the feeds into an observable collection at startup I then create one instance of the control for each feed and add them all to a listbox - pretty simple stuff really.
XAML code is below:
<UserControl x:Class="MyReader.FeedControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
Loaded="UserControl_Loaded" >
<Grid x:Name="LayoutRoot" Height="50" Background="Black" HorizontalAlignment="Left" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="70"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="70"/>
</Grid.ColumnDefinitions>
<CheckBox Name="Select" Grid.Column="0" IsChecked="{Binding IsSelected}" Margin="-5,-16" Checked="Select_Checked" Background="White"/>
<TextBlock Name="FeedName" Grid.Column="1" Text="{Binding FeedName}" Opacity="1" Margin="-20" VerticalAlignment="Center" FontSize="24"
MouseLeftButtonUp="FeedName_MouseLeftButtonUp" Height="32" Width="360"/>
<TextBlock Name="UnreadItems" Grid.Column="2" Text="{Binding UnreadItems}" Opacity="1" Padding="2" VerticalAlignment="Center" HorizontalAlignment="Right"
FontSize="24" MouseLeftButtonUp="FeedName_MouseLeftButtonUp" />
</Grid>
When the orientation changes of the page the listbox of Feedcontrol items is on I want the feed name textblock to change to the correct size (560px for landscape, 360px for portrait) so I assumed by setting the grid column width to "*" or "Auto" and setting no width for the textblock it would automatically resize but it only resizes to the width of it's text and not the full width.
So then I tried setting the textblock to the default portrait size (360) in the XAML and on the page orientation change event I call the following Method in each instance of the FeedControl currently in the ListBox:
public void ChangeOrientation(bool isLandscape)
{
if (isLandscape)
{
this.LayoutRoot.Width = App.LandscapeWidth; //700
this.FeedName.Width = App.LandscapeItemWidth; //560
}
else
{
this.LayoutRoot.Width = App.PortraitWidth; //480
this.FeedName.Width = App.PortraitItemWidth; //360
}
this.InvalidateArrange();
this.InvalidateMeasure();
}
However, this doesn't work either (no matter what I try) so I am confused about how best to do this... I know there must be a really simple way but so far I've not found it.
Can anybody point me in the right direction please?
Mike
PS sorry for the length of the post... so long for such a simple problem!!

You should set the HorizontalAlignment and HorizontalContentAlignment to HorizontalAlignment.Stretchfor the ListBoxItems which have your control. In addition, set the design width/design height of your control.
Here's an example of one of my controls I have in a listbox, that stretches in landscape mode.
<UserControl x:Class="SabWatch.Resources.Controls.ProgressBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
d:DesignHeight="480" d:DesignWidth="480">
<Grid x:Name="LayoutRoot" Style="{StaticResource AppBackgroundStyle}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
</Grid>
</UserControl>
And here's an example of setting the alignment properties in code. you can also do this in XAML (and possibly using a style and giving the ListBox a ItemContainerStyle)
var lbi = new ListBoxItem();
var box = new ProgressBox();
...
lbi.Tag = queueObject;
lbi.Content = box;
lbi.HorizontalAlignment = HorizontalAlignment.Stretch;
lbi.HorizontalContentAlignment = HorizontalAlignment.Stretch;

Where u are placing this control, that you are not mentioned . I think u are placing this control inside a Phone page ; like placing any other control. If so better u manage orientation related stuffs in that page( Container page ) instead of making adjustment in the control. I Think this will solve your issue.

Related

UWP community toolkit RoundImageEx image not showing

I have the following DataTemplate for my GridView
<DataTemplate x:Key="GridViewItemTemplate">
<Grid Margin="5,10" MaxWidth="80">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!-- Vendor image-->
<toolkitControls:RoundImageEx IsCacheEnabled="True" PlaceholderSource="/Assets/Samples/AnotherSampleImage.png" PlaceholderStretch="Uniform" Source="/Assets/Samples/SampleImage.png" Stretch="Uniform" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<TextBlock Grid.Row="1" Padding="0,5,0,0" Text="{Binding NameEn}" HorizontalAlignment="Center" TextWrapping="Wrap" FontSize="{StaticResource SmallTextSize}"/>
</Grid>
</DataTemplate>
Here I'm using RoundImageEx control from UWP community toolkit. The problem is that neither Image not ImagePlaceholder is not showing.
I've tried using the ImageEx control from the toolkit and it works great.
GridView using ImageEx in the DataTemplate (it works just fine)
GridView using RoundImageEx in the DateTemplate (images not showing)
Is it some kind of a bug or I'm doing something wrong?
Method 1:
Set HorizontalAlignment and VerticalAlignment as Stretch for your RoundImageEx control
Code Sample
<toolkitControls:RoundImageEx IsCacheEnabled="True" PlaceholderSource="/Assets/Samples/AnotherSampleImage.png"
PlaceholderStretch="Uniform" Source="/Assets/Samples/SampleImage.png" Stretch="Uniform"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
Method 2:
Set Width and Height for your RoundImageEx control
Code Sample
<toolkitControls:RoundImageEx IsCacheEnabled="True" PlaceholderSource="/Assets/Samples/AnotherSampleImage.png"
PlaceholderStretch="Uniform" Source="/Assets/Samples/SampleImage.png" Stretch="Uniform"
Width="100" Height="100"/>

Change GridView's SelectedItem while selecting datatemplate control in phone application

The GridView in MainPage.xaml binds to an ObservableCollection of Employee. And the Employee class has got Amount(double) property that I want to edit through a TextBox. And finally when the text is entered I want to do some operation on the remaining Employee objects. I am able to get at the edited object via the INotifyPropetyChanged/PropertyChanged. But I think I cannot perform the operation here since it will trigger a cyclic PropertyChange for each of the object's update that I may perform on the other objects? Ideally, I should rely on the TextChanged event of the TextBox to do this.
The problem that I face is I am not able to get the edited object selected against the GridView's SelectedItem(SelectedEmployee). I can manage to get it selected only if I click/tap it outside the TextBox and within the row but not when I click directly in the TextBox. I wonder there is a way to trigger/update the GridView's SelectedItem when the TextBox is directly tapped?
Below my MainPage.xaml
<storeApps:VisualStateAwarePage
x:Class="SimpleCurrency.Views.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:SimpleCurrency.Views"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:storeApps="using:Microsoft.Practices.Prism.StoreApps"
xmlns:mvvm="using:Microsoft.Practices.Prism.Mvvm"
mc:Ignorable="d"
mvvm:ViewModelLocator.AutoWireViewModel="True"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<GridView Margin="12,20,12,0" ItemsSource="{Binding Employees}" x:Name="grdEmployees"
ItemTemplate="{StaticResource EmployeeGridTemplate}" SelectedItem="{Binding SelectedEmployee, Mode=TwoWay}">
</GridView>
And the DataTemplate EmployeeTemplate
<DataTemplate x:Key="EmployeeGridTemplate">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="100"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<ComboBox Width="120" ItemsSource="{Binding DataContext.Departments, ElementName=grdEmployees, Mode=TwoWay}" DisplayMemberPath="Code" SelectedValuePath="Code"/>
<TextBox Grid.Row="0" Grid.Column="1" Text="{Binding Path=Amount, Mode=TwoWay}" InputScope="Number">
<!--TODO: Need to get at text chagned event-->
<interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="TextChanged">
<Core:InvokeCommandAction Command="{Binding DataContext.ConvertCommand, ElementName=grdConversions}"
CommandParameter="{Binding }"/>
</Core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</TextBox>
</Grid>
</DataTemplate>
Open to any suggestion/workaround
The tap event of the TextBox is preventing the GridView from noticing the tap event because it is "below" the TextBox tap area.
You should be able to determine which employee is bound to your TextBox (Databinding Context) and use this information to programmatically set the selected item of your GridView to the Employee Instance.

How to position a button using grid row and column definitions?

I've set up a Windows Phone 8.1 project and right now I'm trying to place a button, in the centered horizontally near the bottom of the layout.
So far I've figured out the following to center the button on the layout, but the
Grid.Row setting doesn't seem to have any effect on the vertical positioning as I expected.
Does anyone know how I can position the button towards the bottom of the screen? At the moment its in the center but half way up the screen, needs to be towards the bottom of the screen.
<Page x:Class="LC_Points.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:LC_Points"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
DataContext="{Binding Source={StaticResource Locator},
Path=MainViewModel}"
mc:Ignorable="d">
<Grid>
<Button Grid.Row="2"
Content="Calculate"
HorizontalAlignment="Center"/>
</Grid>
</Page>
Before you set Grid.Row property of an element, first you have to define the rows of the Grid.
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Button Grid.Row="1" Content="Click Me!" />
</Grid>
If you change the Height properties of the RowDefinitions, you can easily position the Button vertically.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="90*"></RowDefinition>
<RowDefinition Height="10*"></RowDefinition>
</Grid.RowDefinitions>
<Button Grid.Row="1" Content="Click Me!" />
</Grid>
10* means 10% of the Grid. Sum of the stars has to be equal 100.

ContentDialog's buttons are not shown in a Windows Phone 8.1 app if the BottomAppBar is defined

I would like to show a ContentDialog on first launch of my app, to show the EULA to the end user.
It seems that if an AppBar is defined in the calling page the two buttons in the dialog are not visible, an empty area with the same size of the command bar area defined in the calling page, is shown instead.
This is the markup on the ContentDialog:
<ContentDialog
x:Class="MyApp.EulaPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:MyApp.Pages"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="TERMS OF USE"
PrimaryButtonText="i agree"
SecondaryButtonText="cancel"
PrimaryButtonClick="OnAgreeButtonClick"
SecondaryButtonClick="OnCancelButtonClick">
<Grid x:Name="ContentPanel" Margin="0,0,0,0" >
<Grid.RowDefinitions>
<RowDefinition Height="524" />
</Grid.RowDefinitions>
<ScrollViewer Grid.Row="0" Margin="0,0,0,2" >
<RichTextBlock IsTextSelectionEnabled="False" TextAlignment="Left" TextIndent="0" FontSize="14" FontFamily="Segoe WP" >
</RichTextBlock>
</ScrollViewer>
</Grid>
The GridRowDefinition has a fixed hight, because the text in the RichTextBlock needs to be scrolled.
I have prepared a sample project that can be found here. The zip file contains also a screenshot showing how I see the dialog.
I had the same problem and I have solved it by modifying/removing Height/Width and Margins of the Contentdialog

Binding height and width of border to half of its children at runtime in windows 8.1 app

I have a user control which have elements like this
<UserControl
x:Class="App2.MyImageControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App2"
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 x:Name="MyGrid" x:FieldModifier="public" ManipulationMode="None" Tapped="MyGrid_Tapped" HorizontalAlignment="Left" VerticalAlignment="Top" >
<Grid.RenderTransform>
<CompositeTransform></CompositeTransform>
</Grid.RenderTransform>
<Border x:Name="MyBorder" x:FieldModifier="public" BorderThickness="1" BorderBrush="Transparent" Width="auto" Height="auto">
<Grid>
<Image x:Name="MyImageO" x:FieldModifier="public" Source="" Width="auto" Height="auto" Stretch="Fill"></Image>
</Grid>
</Border>
</Grid>
I want to bind MyBorder width and height to half of MyImageO width and height at runtime.How do I achieve that .
You could try using the MultiplyConverter to convert a bound value to half of it, but ActualWidth and ActualHeight aren't bindable - they don't raise change notifications. Your best bet is to simply handle SizeChanged events and then set the dimensions of the border based on ActualWidth and ActualHeight of the image.