How to move a WPF control in code?
Posted: (EET/GMT+2)
Recently, I needed to control the position of a control on my WPF form programmatically using C#, and wanted to share the tip on as I found it difficult to find a solution from the internet. In many other user interface frameworks, including .NET frameworks, this is trivial: you just set the position of the control which you want to move. For example, in WinForms, you would simply set the Left and Top properties, for instance.
WPF, on the other hand, is different. To simplify things a bit, you can think about it this way: the container component defines the position of its child elements. Thus, an individual control – say a button – does not control where it is positioned itself. Instead, it is job of the container – for instance a grid – to position it.
Although this is not exactly as written above, the solution to component runtime moving can be found easier if you think this way. The truth is each container works a little differently, and the solution for a WPF grid control works like the code below.
First, here is a block of XAML code (note how you should give your grid a name so that you can refer to it in code):
<Window x:Class="WpfApplication4.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"> <Grid Name="myGrid"> <Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="36,51,0,0" Name="button1" VerticalAlignment="Top" Width="75" /> </Grid> </Window>
With the given grid and a button set, you notice that the margins for the button are 36 and 51 pixels. This means that the button can be thought of defining for itself an invisible "border" (i.e. a margin) for 36 pixels from the left border and 51 pixels from the top. By changing these margin values, you could then move the button relative to the grid.
Given this information, you might first think about simply setting the Margin property of the control. Your first attempt might be the following:
// attempt to move button down by 20 pixels button1.Margin.Top += 20;
Although this looks fine, it unfortunately does not work. Instead, you will get an compiler error saying:
Cannot modify the return value of 'System.Windows.FrameworkElement.Margin' because it is not a variable.
So you need to find an alternative solution that is slightly different. Here's how:
Thickness position = button1.Margin; position.Top += 20; button1.Margin = position;
Since this solution is easy, but slightly inconvenient, you could write two helper methods:
internal static class WpfMoveHelpers
{
internal static void MoveDown(
this FrameworkElement control, int yChange)
{
Thickness position = control.Margin;
position.Top += yChange;
control.Margin = position;
}
internal static void MoveRight(
this FrameworkElement control, int xChange)
{
Thickness position = control.Margin;
position.Left += xChange;
control.Margin = position;
}
}
With these methods in place, you could simply say things like:
button1.MoveDown(20); button1.MoveRight(10);
Hope this helps! Of course, to be extract smooth, you could animate the property change...
Keywords: HowTo, move WPF control, component, move at runtime, C#, in code.