Straightaway porting is not possible but can we "simulate" this using MultiBinding
Mind you that this is very tightly coupled solution and may not perform well if many of such bindings are used on a page...
Two must haves ...
- It accepts the delay in milliseconds in a single item
ArrayList
as a converter parameter.
- Every such delayed binding must carry its own instance of converter parameter.
The Test XAML is as below...
<TextBlock xmlns:Collections="clr-namespace:System.Collections;assembly=mscorlib"
xmlns:System="clr-namespace:System;assembly=mscorlib" >
<TextBlock.Resources>
<local:DelayHelper x:Key="DelayHelper"/>
<Collections:ArrayList x:Key="MultiConverterParameter">
<System:Int32>2000</System:Int32>
</Collections:ArrayList>
</TextBlock.Resources>
<TextBlock.Text>
<MultiBinding UpdateSourceTrigger="LostFocus"
Converter="{StaticResource DelayHelper}"
ConverterParameter="{StaticResource MultiConverterParameter}">
<Binding Path="Text" ElementName="MyTextBox" Mode="OneWay" />
<Binding RelativeSource="{RelativeSource Self}"/>
<Binding BindsDirectlyToSource="True"
Source="{x:Static TextBlock.TextProperty}"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
<TextBox x:Name="MyTextBox" Text="Test..."/>
In this example a TextBlock
renders of what is typed in TextBox
below after a 2 seconds delay. The TextBox.Text
is primary source of data.
DelayHelper
is multi converter that works as shown below...
public class DelayHelper : IMultiValueConverter
{
#region IMultiValueConverter Members
public object Convert(
object[] values,
Type targetType,
object parameter,
System.Globalization.CultureInfo culture)
{
var sourceElement = values[1] as FrameworkElement;
var dp = values[2] as DependencyProperty;
var paramArray = parameter as ArrayList;
var existingValue
= paramArray != null && paramArray.Count == 2
? paramArray[1] : sourceElement.GetValue(dp);
var newValue = values[0];
var bndExp = BindingOperations.GetMultiBindingExpression(sourceElement, dp);
var temp = new DispatcherTimer() { IsEnabled = false };
var dspTimer
= new DispatcherTimer(
new TimeSpan(0,0,0,0, int.Parse(paramArray[0].ToString())),
DispatcherPriority.Background,
new EventHandler(
delegate
{
if (bndExp != null && existingValue != newValue)
{
var array
= bndExp.ParentMultiBinding.ConverterParameter
as ArrayList;
var existingInterval = array[0];
array.Clear();
array.Add(existingInterval);
array.Add(newValue);
bndExp.UpdateTarget();
}
temp.Stop();
}),
sourceElement.Dispatcher);
temp = dspTimer;
dspTimer.Start();
return existingValue;
}
public object[] ConvertBack(
object value,
Type[] targetTypes,
object parameter,
System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
#endregion
}
So this code makes use of the facts that
- MultiBinding can accept the target UI element (
TextBlock
) and its dependency property (TextBlock.TextProperty
) that itself is multi-bound.
- Once bound the multi binding cannot alter its properties including the
ConveterParameter
. But the converter parameter itself can be a reference object that maintains its reference throughout the binding is active e.g. ArrayList
.
- The
DispatcherTimer
has to stop after its first Tick
. Hence we use of the temp
variable is very essential.
- The updates make 2 converter passes for each source text update. There is no escpae from this behavior. This may cause slowness is many delayed bindings are used.
- Make sure you do not share the same converter parameter among multiple delayed bindings
Let me know if this helps...