I have the following sample code that zooms each time a button is pressed:
XAML:
<Window x:Class="WpfApplication12.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Canvas x:Name="myCanvas">
<Canvas.LayoutTransform>
<ScaleTransform x:Name="myScaleTransform" />
</Canvas.LayoutTransform>
<Button Content="Button"
Name="myButton"
Canvas.Left="50"
Canvas.Top="50"
Click="myButton_Click" />
</Canvas>
</Window>
*.cs
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void myButton_Click(object sender, RoutedEventArgs e)
{
Console.WriteLine("scale {0}, location: {1}",
myScaleTransform.ScaleX,
myCanvas.PointToScreen(GetMyByttonLocation()));
myScaleTransform.ScaleX =
myScaleTransform.ScaleY =
myScaleTransform.ScaleX + 1;
Console.WriteLine("scale {0}, location: {1}",
myScaleTransform.ScaleX,
myCanvas.PointToScreen(GetMyByttonLocation()));
}
private Point GetMyByttonLocation()
{
return new Point(
Canvas.GetLeft(myButton),
Canvas.GetTop(myButton));
}
}
the output is:
scale 1, location: 296;315
scale 2, location: 296;315
scale 2, location: 346;365
scale 3, location: 346;365
scale 3, location: 396;415
scale 4, location: 396;415
as you can see, there is a problem, that I thought solve by using Application.DoEvents();
but... it does not exist a priori in .NET 4.
What to do?
Try something like this
Well, I just hit a case where I start work on a method that runs on the Dispatcher thread, and it needs to block without blocking the UI Thread. Turns out that msdn explains how to implement a DoEvents() based on the Dispatcher itself:
(taken from Dispatcher.PushFrame Method)
The old Application.DoEvents() method has been deprecated in WPF in favor of using a Dispatcher or a Background Worker Thread to do the processing as you have described. See the links for a couple of articles on how to use both objects.
If you absolutely must use Application.DoEvents(), then you could simply import the system.windows.forms.dll into your application and call the method. However, this really isn't recommended, since you're losing all the advantages that WPF provides.
If you need just update window graphic, better use like this
Since the introduction of
async
andawait
its now possible to relinquish the UI thread partway through a (formerly)* synchronous block of code usingTask.Delay
, e.g.I'll be honest, I've not tried it with the exact code above, but I use it in tight loops when I'm placing many items into an
ItemsControl
which has an expensive item template, sometimes adding a small delay to give the other stuff on the UI more time.For example:
On Windows Store, when there's a nice theme transition on the collection, the effect is quite desirable.
Luke
seems to work as well.