wp7 slider hangs up - silverlight

I am trying to use a slider control. It's just the simple control. Nothing fancy. But I run into an issue that is confusing me.
If I put the control on a test page (blank with nothing else) and navigate to it immediately after the app launches , I can slide it around perfectly. But if I navigate to another page first and then to the test page. I get a very weird behavior. The slider control moves in steps. It seems as if it hangs up or is losing focus.
I'm using wp7.1 and I've tested in the emulator and on the phone. Both give me the same result. I don't even know where to start solving this, but i definitely need a slider and for it to move smoothly.
Any ideas?
revised to include xaml:
<phone:PhoneApplicationPage
x:Class="WP7ListBoxSelectedItemStyle.TestPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
xmlns:local="clr-namespace:WP7ListBoxSelectedItemStyle"
xmlns:my="clr-namespace:colordata_controls;assembly=colordata_controls"
shell:SystemTray.IsVisible="True" xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit">
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--TitlePanel contains the name of the application and page title-->
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock x:Name="ApplicationTitle" Text="IPO" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock x:Name="PageTitle" Text="Test" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="8,17,16,-17">
<Slider Height="84" HorizontalAlignment="Left" Margin="10,10,0,0" Name="slider1" VerticalAlignment="Top" Width="460" />
</Grid>
</Grid>
here is a link to a video of it in action in the emulator. https://vimeo.com/36428677

so, I still don't know why the slider sticks that way, but in order to keep moving forward I created my own slider. Hopefully this code helps someone else.
xaml:
<UserControl
x:Name="userControl"
x:Class="controls.pSlider"
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"
d:DesignWidth="76" d:DesignHeight="400" Background="Gray" Foreground="White">
<Grid x:Name="LayoutRoot" Background="Transparent" MouseMove="LayoutRoot_MouseMove" MouseLeftButtonDown="LayoutRoot_MouseLeftButtonDown">
<Grid.RowDefinitions>
<RowDefinition Height="10"/>
<RowDefinition/>
<RowDefinition Height="10"/>
</Grid.RowDefinitions>
<Rectangle x:Name="colorBar" Margin="20,6" Width="10" Fill="{Binding Background, ElementName=userControl}" Grid.Row="1"/>
<Grid x:Name="g_container" Grid.Row="1" Margin="0,1,0,13">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="0"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid x:Name="g_thumb" Height="0" VerticalAlignment="Top" Grid.Row="1">
<Canvas Height="0" VerticalAlignment="Top">
<Path Data="M0,0 L1,0 L1.2,0.5 L1,1 L0,1 z" Margin="0" Stretch="Fill" UseLayoutRounding="False" Width="33" RenderTransformOrigin="0.5,0.5" StrokeThickness="0" Fill="{Binding Foreground, ElementName=userControl}" Height="12" d:LayoutOverrides="VerticalAlignment"/>
<Path Data="M0.3,0.5 L0.5,0 L1.5,0 L1.5,1 L0.5,1 z" Margin="0" Stretch="Fill" UseLayoutRounding="False" Width="33" RenderTransformOrigin="0.5,0.5" StrokeThickness="0" Fill="{Binding Foreground, ElementName=userControl}" Height="12" Canvas.Left="43" d:LayoutOverrides="VerticalAlignment"/>
</Canvas>
</Grid>
<Rectangle x:Name="r_lifter" Margin="0" Grid.Row="2" Height="188" StrokeThickness="0"/>
</Grid>
</Grid>
code:
namespace controls {
public partial class pSlider : UserControl {
public event RoutedEventHandler ValueChanged;
public static readonly DependencyProperty MaxProperty =
DependencyProperty.Register("Maximum", typeof(double), typeof(pSlider), new PropertyMetadata(100.0));
public double Maximum {
get { return (double)GetValue(MaxProperty); }
set { SetValue(MaxProperty, value); }
}
public static readonly DependencyProperty MinProperty =
DependencyProperty.Register("Minimum", typeof(double), typeof(pSlider), new PropertyMetadata(0.0));
public double Minimum {
get { return (double)GetValue(MinProperty); }
set { SetValue(MinProperty, value); }
}
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register("Value", typeof(double), typeof(pSlider), new PropertyMetadata(50.0));
public double Value {
get { return (double)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
public pSlider() {
InitializeComponent();
Loaded += new RoutedEventHandler(pSlider_Loaded);
}
void pSlider_Loaded(object sender, RoutedEventArgs e) {
if (Value > Maximum)
Value = Maximum;
else if (Value < Minimum)
Value = Minimum;
double min = 0;
double max = g_container.ActualHeight;
r_lifter.Height = Value / (Maximum - Minimum) * (max - min);
}
private Point Position;
private void LayoutRoot_MouseMove(object sender, MouseEventArgs e) {
Point newPosition = e.GetPosition((UIElement)sender);
double delta = newPosition.Y - Position.Y;
double temp = r_lifter.Height - delta;
if (temp > g_container.ActualHeight)
r_lifter.Height = g_container.ActualHeight;
else if (temp < 0)
r_lifter.Height = 0;
else
r_lifter.Height = temp;
double min = 0;
double max = g_container.ActualHeight;
Value = r_lifter.Height / (max - min) * (Maximum - Minimum);
Value = Math.Floor(Value);
RoutedEventHandler handler = ValueChanged;
if (handler != null)
handler(this, e);
Position = e.GetPosition((UIElement)sender);
}
private void LayoutRoot_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) {
Position = e.GetPosition((UIElement)sender);
}
}
}

Related

IsAvailable always false with Kinect Studio on IsAvailableChanged

Environ: Kinect 2.0 SDK, Kinect Studio, Windows 10, WPF
e.IsAvailailable is always returning false when I'm driving my programming via the Kinect Studio ( https://msdn.microsoft.com/en-us/library/microsoft.kinect.kinectsensor.isavailable.aspx ). I would think it would return true if it were receiving data. Note the BodyReader frames are arriving even though the sensor started unavailable and never tripped the IsAvailableChanged handler. Note the BodyBasics-WPF SDK 2.0 sample behaves the same way.
A number of code samples stop if they get e.IsAvailable=false. Probably a bad move if you are using Kinect Studio and playback.
Bug? Feature? Lack of documentation?
Kinect against Kinect Studio - IsAvailable = false
Kinect against Physical Kinect - IsAvailable = true
Code and XAML below...
public partial class MainWindow : Window
{
private KinectSensor m_kinectSensor = null;
private BodyFrameReader m_bodyReader;
private Body[] m_bodies = null;
public MainWindow()
{
this.m_kinectSensor = KinectSensor.GetDefault();
this.m_kinectSensor.IsAvailableChanged += KinectSensor_IsAvailableChanged;
this.m_kinectSensor.Open();
// hook the body stuff
this.m_bodyReader = m_kinectSensor.BodyFrameSource.OpenReader();
this.m_bodyReader.FrameArrived += BodyReader_FrameArrived;
InitializeComponent();
Msg("MainWindow c'tor completed");
}
private void BodyReader_FrameArrived(object sender, BodyFrameArrivedEventArgs e)
{
Msg(String.Format("BodyReader_FrameArrived: {0}" , e.FrameReference.RelativeTime.ToString()));
}
private void KinectSensor_IsAvailableChanged(object sender, IsAvailableChangedEventArgs e)
{
System.Diagnostics.Debug.WriteLine( "KinectSensor_IsAvailableChanged: e.IsAvailable=" + e.IsAvailable.ToString() );
TextBlock_StatusBar.Text = "KINECT SENSOR STATUS: " + e.IsAvailable.ToString();
}
private void Msg ( string s )
{
if (s.Length <= 0) s = "ready";
TextBlock_Msg.Text = s;
}
}
}
XAML
<Window x:Class="FaceNSkinWPF.MainWindow"
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"
xmlns:local="clr-namespace:FaceNSkinWPF"
mc:Ignorable="d"
Title="MainWindow"
Height="600" Width="800"
>
<Grid Margin="10,10,10,10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal" HorizontalAlignment="Center">
<Button Content="ButtonOne" Width="150" Height="30" Margin="10"/>
<Button Content="ButtonOne" Width="150" Height="30" Margin="10"/>
<Button Content="ButtonOne" Width="150" Height="30" Margin="10"/>
</StackPanel>
<Viewbox Grid.Row="1" HorizontalAlignment="Center">
<Image Source="{Binding ImageSource}" Stretch="UniformToFill" />
</Viewbox>
<StackPanel Grid.Row="2" Orientation="Vertical">
<TextBlock x:Name="TextBlock_StatusBar" Height="20" Foreground="Black" FontWeight="Bold" Text="KINECT SENSOR STATUS: unknown"/>
<TextBlock x:Name="TextBlock_Msg" Height="20" Foreground="Blue" FontWeight="Bold" Text="ready"/>
</StackPanel>
</Grid>

WPF Binding two levels of UserControl

let's explain a little bit my issue, i wrote a code of an application that show a usercontrol with bindings that i'm trying to set to another sub-usercontrol. I'm using a model that i've set to my MainWindow.xaml.
THE PROBLEM IS:
The usercontrol innerusercontrol doesn't show changes in the bindings. I guess i made a mistake, but i don't know where and how to fix it. I read several posts but no body answer them with a specific code-line. Could any body help me?
I'll appreciate an answer. Thanks
MainWindow.xaml
<Window x:Class="DependencyProperties.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:DependencyProperties"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="3*"/>
<RowDefinition/>
</Grid.RowDefinitions>
<local:DisplayProduct x:Name="ucDisplay" Grid.Row="1" Height="110"/>
<Button Grid.Row="2" Click="Button_Click">Apply circle visibility false/true</Button>
</Grid>
</Window>
MainWindow.xaml.cs
public partial class MainWindow : Window
{
public static ProductModel product;
public MainWindow()
{
InitializeComponent();
product = new ProductModel() { IsActivo = true, Descuento = 15.00, Importe = 100.00, Total = 85.00 };
ucDisplay.DataContext = product;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Console.WriteLine("Antes " + product.IsActivo);
product.IsActivo = !product.IsActivo;
Console.WriteLine("Despues" + product.IsActivo);
}
}
DisplayProductUserControl.xaml
<UserControl x:Class="DependencyProperties.DisplayProductUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:DependencyProperties"
mc:Ignorable="d" x:Name="win_Display"
d:DesignHeight="80" d:DesignWidth="500">
<UserControl.Resources>
<Style TargetType="TextBlock">
<Setter Property="FontSize" Value="18"/>
<Setter Property="FontWeight" Value="Light"/>
</Style>
</UserControl.Resources>
<Grid>
<Viewbox>
<Grid Width="{Binding ElementName=win_Display, Path=ActualWidth}" Height="{Binding ElementName=win_Display, Path=ActualHeight}">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Price: "/>
<TextBlock Text="$"/>
<TextBlock Text="{Binding Path=Price}"/>
</StackPanel>
<StackPanel Grid.Column="1" Orientation="Horizontal">
<TextBlock Text="Discount: "/>
<TextBlock Text="$"/>
<TextBlock Text="{Binding Path=Discount}"/>
</StackPanel>
<StackPanel Grid.Column="2" Orientation="Horizontal">
<TextBlock Text="Total: "/>
<TextBlock Text="$"/>
<TextBlock Text="{Binding Path=Total}"/>
</StackPanel>
<local:InnerUserControl Grid.Column="0" Grid.Row="1">
<local:InnerUserControl DataContext="{Binding Path=IsActive,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=UserControl}}"/>
</local:InnerUserControl>
</Grid>
</Viewbox>
</Grid>
</UserControl>
InnerUserControl *THE PROBLEM IS HERE <------------------ *
<UserControl x:Class="DependencyProperties.InnerUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d" x:Name="win_inner"
d:DesignHeight="40" d:DesignWidth="100">
<UserControl.Resources>
<BooleanToVisibilityConverter x:Key="VisibilityConverter"/>
</UserControl.Resources>
<Grid Width="{Binding ElementName=win_inner, Path=ActualWidth}">
<TextBlock Text="{Binding Path=IsActive}" FontSize="15"/>
**<!-- HERE IS THE PROBLEM I DOESN'T SHOW CHANGES WHEN IsActive is false/true -->**
<Ellipse Height="{Binding ElementName=win_inner, Path=ActualHeight}" Width="{Binding RelativeSource={RelativeSource Self}, Path=ActualHeight}" Fill="Red"
Visibility="{Binding Path=IsActive, Converter={StaticResource VisibilityConverter}}" HorizontalAlignment="Right"></Ellipse>
</Grid>
</UserControl>
ProductoModel
public class ProductModel : INotifyPropertyChanged
{
private double price;
public double Price
{
get { return price; }
set { price= value; }
}
private double discount;
public double Discount
{
get { return discount; }
set { discount= value; }
}
private double total;
public double Total
{
get { return total; }
set { total = value; }
}
private bool isActive;
public bool IsActive
{
get { return isActive; }
set { isActive = value; }
}
protected void RaisePropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
like dnr3 commented already,
Add RaisePropertyChanged method in your 'Product Model' class.
public bool IsActive
{
get { return isActive; }
set
{
isActive = value;
RaisePropertyChanged("IsActive");
}
}
View never changes until it gets 'PropertyChanged' Event.

OOB Silverlight and content scale on window resize

Good morning,
I faced problem when doing scaleTransform on the content when OOB Silverlight application's window gets resized. The code looks very simple
xaml
<UserControl x:Class="SilverlightApplication1.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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<Grid x:Name="LayoutRoot" Background="Aquamarine" RenderTransformOrigin="0,0">
<Rectangle Fill="Aqua" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
<Grid VerticalAlignment="Center" HorizontalAlignment="Center" Height="150">
<TextBlock FontSize="20" Text="Hello World" Margin="5" VerticalAlignment="Top" HorizontalAlignment="Center"/>
<Button Content="Button" VerticalAlignment="Bottom" HorizontalAlignment="Center"/>
</Grid>
</Grid>
</UserControl>
C#
public MainPage()
{
InitializeComponent();
SizeChanged += MainPage_SizeChanged;
}
void MainPage_SizeChanged(object sender, SizeChangedEventArgs e)
{
ScaleTransform scaleTransform = new ScaleTransform();
scaleTransform.ScaleX = (Application.Current.MainWindow.Width / 500f);
scaleTransform.ScaleY = (Application.Current.MainWindow.Height / 500f);
scaleTransform.CenterX = 0;
scaleTransform.CenterY = 0;
// this.RenderTransform doesn't work either.
LayoutRoot.RenderTransform = scaleTransform;
}
The content gets scaled when the main window is resized, but, for some reason, I see white background of the window when scaling down. It seems that the content is scaled down faster than window and I don't know what I am doing wrong. The code seems logical and should work, shouldn't it?
The LayoutTransformer saved my day. I have changed the code and xaml as follows and everything works now. Code may need a little tweaking though.
xaml
<UserControl x:Class="SilverlightApplication1.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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:layout="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Layout.Toolkit"
mc:Ignorable="d"
d:DesignHeight="500" d:DesignWidth="500">
<layout:LayoutTransformer x:Name="LayoutTransformer">
<layout:LayoutTransformer.Content>
<Grid x:Name="LayoutRoot" Background="AntiqueWhite">
<Rectangle Fill="Aqua" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
<Grid VerticalAlignment="Center" HorizontalAlignment="Center" Height="150">
<TextBlock FontSize="20" Text="Hello World" Margin="5" VerticalAlignment="Top" HorizontalAlignment="Center"/>
<Button Content="Button" VerticalAlignment="Bottom" HorizontalAlignment="Center"/>
</Grid>
</Grid>
</layout:LayoutTransformer.Content>
<layout:LayoutTransformer.LayoutTransform>
<ScaleTransform x:Name="ContentScale" CenterX="0" CenterY="0" ScaleX="1" ScaleY="1" />
</layout:LayoutTransformer.LayoutTransform>
</layout:LayoutTransformer>
</UserControl>
C#
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
SizeChanged += MainPage_SizeChanged;
}
void MainPage_SizeChanged(object sender, SizeChangedEventArgs e)
{
double yScale = ActualHeight / 500f;
double xScale = ActualWidth / 500f;
double value = GetScale(xScale, yScale);
ContentScale.ScaleX = value;
ContentScale.ScaleY = value;
LayoutTransformer.ApplyLayoutTransform();
}
private double GetScale(double xScale, double yScale)
{
return Math.Max(0.1, Math.Min(xScale, yScale));
}
}

DispatchHelper open new window

I am using the DispatchHelper from MVVM Light to open a new window while a calculation is being performed. The window contains a simple label and button. When I use the Show() method the window will appear when the calculation starts and will close when the calculation ends but the label and button are not in the window.
I have tried using the ShowDialog() method before the calculation starts and does show the label and button on the window. However, the ShowDialog doesn't return until the window gets closed. Therefore, the window stay open and the calculation does not get performed.
Would anyone have some advise on how to work through this issue?
public RelayCommand ShowPopupControl
{
get
{
return _showPopupControl
?? (_showPopupControl = new RelayCommand(
() => {
DispatcherHelper.CheckBeginInvokeOnUI(() =>
{
var ww = new WorkingWindow();
ww.ShowDialog();
var loop = new LoopData();
loop.DoSomeLoops();
ww.Close();
});
}));
}
}
public class LoopData
{
public void DoSomeLoops()
{
for (int i = 0; i < 10000; i++)
{
System.Diagnostics.Debug.WriteLine(i);
}
}
}
<controls:MetroWindow
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Custom="http://metro.mahapps.com/winfx/xaml/controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="MetroSpinnerPractice.WorkingWindow"
xmlns:controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
Title="WorkingWindow" Height="200" Width="300">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel HorizontalAlignment="Center" Height="75" Margin="5" Grid.Row="0" VerticalAlignment="Center" Width="275" Orientation="Horizontal">
<Label Content="Working...."
VerticalAlignment="Center"
Margin="60,20,0,20"
FontSize="21.333"
HorizontalAlignment="Right"
Width="120"
Height="40"/>
</StackPanel>
<Button x:Name="btnCancelWork" Grid.Row="1"
Content="Cancel"
Width="100"
Height="20"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Margin="0"
ToolTip="cancel current routine"/>
</Grid>

Scrollable form control in Windows Phone 8

How do I make a scrollable form similar to that of the Phone Contact input panel in Windows Phone 8.1?
The current method of StackPanel inside a ScrollViewer restricts scrolling when the SIP launches and I have to hit back button to choose other TextBoxes.
This is not an idea UX situation and I've tried a few options of the web.
Increasing the StackPanel's height beyond its necessary size by about
350 pixels - didn't work, as it displaces the form unevenly and
doesn't return to normal
Creating a ListBox as suggested in another site online didn't change anything either
Increasing the down margin of the last control didn't help either
check the below code which has worked fine for me.
Chat.xaml.cs
using System;
using System.ComponentModel;
using System.Windows.Controls;
using System.Windows.Input;
using System.Linq;
using System.Windows;
using System.Windows.Data;
using System.Windows.Media;
using Microsoft.Phone.Controls;
using PhoneApplicationPage = Microsoft.Phone.Controls.PhoneApplicationPage;
namespace LIV.View
{
// ReSharper disable once RedundantExtendsListEntry
public partial class Chat : PhoneApplicationPage
{
private bool _flag;
public Chat()
{
InitializeComponent();
}
#region Static Chat Header WorkAround
public double OldHeight;
private TranslateTransform _translateTransform;
#region TranslateY dependency property
public static readonly DependencyProperty TranslateYProperty = DependencyProperty.Register(
"TranslateYProperty", typeof(double), typeof(Chat), new PropertyMetadata(default(double), PropertyChangedCallback));
private static void PropertyChangedCallback(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
var chat = o as Chat;
if (chat != null)
{
chat.UpdateTopMargin((double)e.NewValue);
}
}
public double TranslateY
{
get { return (double)GetValue(TranslateYProperty); }
set { SetValue(TranslateYProperty, value); }
}
#endregion
private void ChatPage_OnLoaded(object sender, RoutedEventArgs e)
{
var transform = ((Application.Current).RootVisual).RenderTransform as TransformGroup;
if (transform != null)
{
_translateTransform = transform.Children.OfType<TranslateTransform>().FirstOrDefault();
if (_translateTransform != null)
{
var binding = new Binding("Y")
{
Source = _translateTransform
};
BindingOperations.SetBinding(this, TranslateYProperty, binding);
}
}
}
private void UpdateTopMargin(double translateY)
{
LayoutRoot.Margin = new Thickness(0, -translateY, 0, 0);
}
#endregion
}
}
Chat.xaml
<phone:PhoneApplicationPage x:Class="LIV.View.Chat"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="Black"
Loaded="ChatPage_OnLoaded"
Orientation="Portrait"
SupportedOrientations="Portrait"
shell:SystemTray.BackgroundColor="#FF5CBFBB"
shell:SystemTray.ForegroundColor="White"
shell:SystemTray.IsVisible="True"
mc:Ignorable="d">
<Grid x:Name="LayoutRoot" Background="White">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Background="#FF5CBFBB">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel>
<TextBlock Foreground="White" Text="{Binding ChatUser.Name}" />
<TextBlock Foreground="White" Text="{Binding ChatTime}" />
</StackPanel>
<Button Grid.Column="1"
BorderThickness="0"
Command="{Binding TerminateCommand}"
Foreground="White">
End Chat
</Button>
</Grid>
<Grid x:Name="ContentPanel" Grid.Row="1">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ListBox x:Name="MessageListBox"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
ItemsSource="{Binding Messages}"
ScrollViewer.VerticalScrollBarVisibility="Visible"
Style="{StaticResource BottomListBoxStyle}">
</ListBox>
<StackPanel x:Name="MessageTextPanel"
Grid.Row="1"
Background="#FF5CBFBB">
<Grid Margin="0,0,0,-10">
<TextBlock FontSize="15" Text="{Binding UserStatus}" />
</Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBox></TextBox>
</Grid>
</StackPanel>
</Grid>
</Grid>
</Grid>
</phone:PhoneApplicationPage>
check: ScrollViewer not scroll up while Keyboard is active
When normal
When SIP open
How about only extending the bottom margin of the StackPanel when the SIP is shown? IIRC there is no straightforward API to test for that, but you could use the focus state of the TextBoxes to check when it appears or disappears.

Resources