Uncategorized

Auto-Updating TextBlock for Silverlight

This textblock usercontrol updates its contents every second. Just set a binding to the text property and voila!

Note that the part inside the Dispatcher BeginInvoke method that gets the binding expression and sets the binding to the parent binding of the binding expression is equivalent to the missing .UpdateTarget() found in WPF.

XAML

<UserControl x:Class="CLARIA.Infrastructure.SL.RichClient.Controls.UpdatingTextBlock"
		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="28" d:DesignWidth="240">
	<TextBlock Name="text" />
</UserControl>

C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Threading;
using System.Windows.Data;
using System.ComponentModel;

namespace CLARIA.Infrastructure.SL.RichClient.Controls
{
public partial class UpdatingTextBlock : UserControl, IDisposable
{
public UpdatingTextBlock()
{
InitializeComponent();

// Set timer
if (!DesignerProperties.GetIsInDesignMode(this))
{
t = new Timer(new TimerCallback(TimerCallbackMethod), null, 0, 1000);
}
}

Timer t;
BindingExpression exp;

public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}

// Using a DependencyProperty as the backing store for Text. This enables animation, styling, binding, etc…
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register(“Text”, typeof(string), typeof(UpdatingTextBlock), new PropertyMetadata(“”));

void TimerCallbackMethod(object target)
{
Dispatcher.BeginInvoke(() =>
{
if (exp == null)
{
exp = GetBindingExpression(UpdatingTextBlock.TextProperty);
}
if (exp != null)
{
SetBinding(UpdatingTextBlock.TextProperty, exp.ParentBinding);
}
text.Text = this.Text;
});
}

~UpdatingTextBlock()
{
Dispose();
}

#region IDisposable Members

bool _disposed = false;

public void Dispose()
{
if (!_disposed)
{
if (t != null)
t.Dispose();
_disposed = true;
}
}

#endregion
}
}