Quick Silverlight Tips: Control Reflection, Control Properties Data Binding, Window Title and Status Bar text (IE only)
Well it was pretty long time since my last post here… I was busy, mostly doing consulting… Now the pressure is eased of alittle, so I hope to write here more.
During this time I heard a couple of questions from clients which were pretty easy to solve but possibly still not obvious.
My first tip today will be about “how to produce reflection under text box” and “emulate PropertyBinding” (like it worked at WPF)
To produce reflection (in case of TextBox) I built Vertical StackPanel with desired TextBox and TextBlock with applied ScaleTransform.
Here sample XAML:
<StackPanel Orientation="Vertical" Width="300" Height="250" Background="Lavender" >
<TextBox x:Name="txtTitle" Width="200" Height="35" Text="Test Text" FontSize="20"/>
<TextBlock x:Name="txtStatus" Width="200" Height="35" Text="Test Text" Margin="0,25" Padding="3,0" FontSize="20">
<TextBlock.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleY="-1"/>
</TransformGroup>
</TextBlock.RenderTransform>
<TextBlock.Foreground>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF000000" Offset="1"/>
<GradientStop Color="#FFFFFFFF" Offset="0"/>
</LinearGradientBrush>
</TextBlock.Foreground>
</TextBlock>
</StackPanel>
In my case I’ve added some Gradient to TextBlock’s foreground to achieve better reflection effect:
The second part (“property binding emulation”) is slightly harder. To emulate “Property Binding” let’s first see how to bind the TextBox.Text property to the TextBlock.Text property.
I prepared simple class, which in my case will hold single string property and will implement INotifyPropertyChanged.
public class TextData : INotifyPropertyChanged
{
string str = "";
public string Text
{
get { return str; }
set
{
str = value;
if (null != PropertyChanged)
PropertyChanged(this, new PropertyChangedEventArgs("Text"));
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
}
Now I can do TwoWay binding of my TextBox.Text property to this class and also OneWay binding of TextBlock.Text property to the same instance. Here the XAML:
<UserControl.Resources>
<SilverlightApplication20:TextData x:Key="TextDataDS" d:IsDataSource="True"/>
</UserControl.Resources>
<StackPanel Orientation="Vertical" Width="300" Height="250" Background="Aqua" >
<TextBox x:Name="txtTitle" Width="150" Height="25" Text="{Binding Mode=TwoWay, Path=Text, Source={StaticResource TextDataDS}}" Margin="5"/>
<TextBox x:Name="txtStatus" Width="150" Height="25" Text="{Binding Mode=OneWay, Path=Text, Source={StaticResource TextDataDS}}" Margin="5"/>
</StackPanel>
Now the class instance will be updated once user will leave the TextBox (Lost Focus) and it will update the TextBlock:
Good, but client wanted to perform update every key press… Thus I created dependency property from TextData type:
public TextData textValue
{
get { return (TextData)GetValue(textValueProperty); }
set { SetValue(textValueProperty, value); }
}
public static readonly DependencyProperty textValueProperty =
DependencyProperty.Register("textValue", typeof(TextData), typeof(Page), null);
In control’s constructor set it to be a DataContext and subscribed to TextBox.KeyUp:
textValue = new TextData();
textValue.Text = "";
txtTitle.KeyUp += new KeyEventHandler(txtTitle_KeyUp);
this.DataContext = textValue;
All left to is is to update my data source at the time of event handlig:
textValue.Text = txtTitle.Text;
The last, but not least I’ve changed a little my XAML, so now TextBox.Text property is databound like following:
Text="{Binding Mode=TwoWay, Path=Text}"
and TextBlock.Text property bounded defind like follows:
Text="{Binding Mode=OneWay, Path=Text}"
Also, I removed TextDataDS (from previous example) because I don't need it anymore. Here it goes:
"Property Binding" and Reflection in Silverlight - Demo
The second tip today will be about changing Page Title dynamically and setting Browsers status text.
Changing page title is really easy – all you have to do is to change “title” property of the document which holds the application:
HtmlPage.Document.SetProperty("title", "Some Text");
Changing status text is very easy in IE, but will not in other browsers: it could work in Firefox for example but it is turned off by default. So my example is for IE folks:
string strAgent = HtmlPage.BrowserInformation.UserAgent;
if (strAgent.IndexOf("MSIE") > -1)
HtmlPage.Window.SetProperty("status", txtStatus.Text);
else
//This browser does not support windows.status messages
Here it goes:
Page Title and Status Bar Text with Silverlight - Demo
Sources for all samples here.
Don’t forget about DevAcademy3 (local event) which will take place at 15 Dec at Avenue, Airport City.
My lecture is DEV303 - Integrating Silverlight 2 into Existing Web Sites (Level 300)
Registration is still open here.
Enjoy,
Alex