locked
Moving an object with onscreen controls. RRS feed

  • Question

  • I want to move on onscreen object with an on screen directional pad and two on screen rotation buttons. Is there any code to make this functional, or is there a built-in functionality I can harness?

    Thanks. 


    Tuesday, July 26, 2011 3:02 PM

Answers

  • There are many ways you can do this. I think if I were to do it I would bind the X and Y values of a rendertransform + the rotation value of a rotatetransform to something in a ViewModel, then your controls would just need to update the values from the VM.

    Example for Silverlight:

    <UserControl
    	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    	xmlns:local="clr-namespace:SilverlightApplication2"
    	x:Class="SilverlightApplication2.MainPage"
    	Width="640" Height="480">
    
    	<Grid x:Name="LayoutRoot" Background="White">
    		<Grid.DataContext>
    			<local:PositionViewModel x:Name="PositionViewModelInstance"/>
    		</Grid.DataContext>
    		<Canvas Margin="0,0,0,100" Background="#49BCFF33">
    			<Rectangle Fill="Red" Height="75" Stroke="Black" Width="75" RenderTransformOrigin="0.5,0.5">
    				<Rectangle.RenderTransform>
    					<CompositeTransform TranslateX="{Binding X}" TranslateY="{Binding Y}" Rotation="{Binding Rotation}"/>
    				</Rectangle.RenderTransform>
    			</Rectangle>
    		</Canvas>
    		<StackPanel Margin="0,0,0,15" Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Bottom">
    			<Button Content="Right" Height="44" Width="75" Click="Right"/>
    			<Button Content="Left" Height="44" Width="75" Click="Left"/>
    			<Button Content="Down" Height="44" Width="75" Click="Down"/>
    			<Button Content="Up" Height="44" Width="75" Click="Up"/>
    			<Button Content="CW" Height="44" Width="75" Click="CW"/>
    			<Button Content="CCW" Height="44" Width="75" Click="CCW"/>
    		</StackPanel>
    	</Grid>
    </UserControl>
    


    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.ComponentModel;
    
    namespace SilverlightApplication2
    {
    	public partial class MainPage : UserControl
    	{
    		public MainPage()
    		{
    			// Required to initialize variables
    			InitializeComponent();
    		}
    
        private PositionViewModel ViewModel
        {
          get
          {
            return this.LayoutRoot.DataContext as PositionViewModel;
          }
        }
    
    		private void Right(object sender, System.Windows.RoutedEventArgs e)
    		{
          this.ViewModel.ChangeX(1.0);
    		}
    
    		private void Left(object sender, System.Windows.RoutedEventArgs e)
    		{
          this.ViewModel.ChangeX(-1.0);
    		}
    
    		private void Down(object sender, System.Windows.RoutedEventArgs e)
    		{
          this.ViewModel.ChangeY(1.0);
    		}
    
    		private void Up(object sender, System.Windows.RoutedEventArgs e)
    		{
          this.ViewModel.ChangeY(-1.0);
    		}
    
    		private void CW(object sender, System.Windows.RoutedEventArgs e)
    		{
          this.ViewModel.ChangeRotation(1.0);
    		}
    
    		private void CCW(object sender, System.Windows.RoutedEventArgs e)
    		{
          this.ViewModel.ChangeRotation(-1.0);
    		}
    	}
    	
    	public class PositionViewModel : INotifyPropertyChanged
    	{
    		private double x;
    		private double y;
    		private double rotation;
    		
    		public double X 
    		{
    			get
    			{
    				return this.x;
    			}
    			set
    			{
    				this.x = value;
            this.OnPropertyChanged("X");
    			}
    		}
    		
    		public double Y
    		{
    			get
    			{
    				return this.y;
    			}
    			set
    			{
    				this.y = value;
            this.OnPropertyChanged("Y");
    			}
    		}
    		public double Rotation
    		{
    			get
    			{
    				return this.rotation;
    			}
    			set
    			{
    				this.rotation = value;
            this.OnPropertyChanged("Rotation");
    			}
    		}
    
        public void ChangeX(double delta)
        {
          this.X += delta;
        }
    
        public void ChangeY(double delta)
        {
          this.Y += delta;
        }
    
        public void ChangeRotation(double delta)
        {
          this.Rotation += delta;
        }
    
        private void OnPropertyChanged(string name)
        {
          if (this.PropertyChanged != null)
          {
            this.PropertyChanged(this, new PropertyChangedEventArgs(name));
          }
        }
    
        public event PropertyChangedEventHandler PropertyChanged;
      }
    }
    


    Tuesday, July 26, 2011 3:38 PM
    Moderator

All replies

  • There are many ways you can do this. I think if I were to do it I would bind the X and Y values of a rendertransform + the rotation value of a rotatetransform to something in a ViewModel, then your controls would just need to update the values from the VM.

    Example for Silverlight:

    <UserControl
    	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    	xmlns:local="clr-namespace:SilverlightApplication2"
    	x:Class="SilverlightApplication2.MainPage"
    	Width="640" Height="480">
    
    	<Grid x:Name="LayoutRoot" Background="White">
    		<Grid.DataContext>
    			<local:PositionViewModel x:Name="PositionViewModelInstance"/>
    		</Grid.DataContext>
    		<Canvas Margin="0,0,0,100" Background="#49BCFF33">
    			<Rectangle Fill="Red" Height="75" Stroke="Black" Width="75" RenderTransformOrigin="0.5,0.5">
    				<Rectangle.RenderTransform>
    					<CompositeTransform TranslateX="{Binding X}" TranslateY="{Binding Y}" Rotation="{Binding Rotation}"/>
    				</Rectangle.RenderTransform>
    			</Rectangle>
    		</Canvas>
    		<StackPanel Margin="0,0,0,15" Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Bottom">
    			<Button Content="Right" Height="44" Width="75" Click="Right"/>
    			<Button Content="Left" Height="44" Width="75" Click="Left"/>
    			<Button Content="Down" Height="44" Width="75" Click="Down"/>
    			<Button Content="Up" Height="44" Width="75" Click="Up"/>
    			<Button Content="CW" Height="44" Width="75" Click="CW"/>
    			<Button Content="CCW" Height="44" Width="75" Click="CCW"/>
    		</StackPanel>
    	</Grid>
    </UserControl>
    


    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.ComponentModel;
    
    namespace SilverlightApplication2
    {
    	public partial class MainPage : UserControl
    	{
    		public MainPage()
    		{
    			// Required to initialize variables
    			InitializeComponent();
    		}
    
        private PositionViewModel ViewModel
        {
          get
          {
            return this.LayoutRoot.DataContext as PositionViewModel;
          }
        }
    
    		private void Right(object sender, System.Windows.RoutedEventArgs e)
    		{
          this.ViewModel.ChangeX(1.0);
    		}
    
    		private void Left(object sender, System.Windows.RoutedEventArgs e)
    		{
          this.ViewModel.ChangeX(-1.0);
    		}
    
    		private void Down(object sender, System.Windows.RoutedEventArgs e)
    		{
          this.ViewModel.ChangeY(1.0);
    		}
    
    		private void Up(object sender, System.Windows.RoutedEventArgs e)
    		{
          this.ViewModel.ChangeY(-1.0);
    		}
    
    		private void CW(object sender, System.Windows.RoutedEventArgs e)
    		{
          this.ViewModel.ChangeRotation(1.0);
    		}
    
    		private void CCW(object sender, System.Windows.RoutedEventArgs e)
    		{
          this.ViewModel.ChangeRotation(-1.0);
    		}
    	}
    	
    	public class PositionViewModel : INotifyPropertyChanged
    	{
    		private double x;
    		private double y;
    		private double rotation;
    		
    		public double X 
    		{
    			get
    			{
    				return this.x;
    			}
    			set
    			{
    				this.x = value;
            this.OnPropertyChanged("X");
    			}
    		}
    		
    		public double Y
    		{
    			get
    			{
    				return this.y;
    			}
    			set
    			{
    				this.y = value;
            this.OnPropertyChanged("Y");
    			}
    		}
    		public double Rotation
    		{
    			get
    			{
    				return this.rotation;
    			}
    			set
    			{
    				this.rotation = value;
            this.OnPropertyChanged("Rotation");
    			}
    		}
    
        public void ChangeX(double delta)
        {
          this.X += delta;
        }
    
        public void ChangeY(double delta)
        {
          this.Y += delta;
        }
    
        public void ChangeRotation(double delta)
        {
          this.Rotation += delta;
        }
    
        private void OnPropertyChanged(string name)
        {
          if (this.PropertyChanged != null)
          {
            this.PropertyChanged(this, new PropertyChangedEventArgs(name));
          }
        }
    
        public event PropertyChangedEventHandler PropertyChanged;
      }
    }
    


    Tuesday, July 26, 2011 3:38 PM
    Moderator
  • Thanks for the help.

    I'm using Blend 3, does that make a difference? The source code doesn't seem to want to recognize the Grid.DataContext and is having some trouble running.

    Thursday, July 28, 2011 12:56 PM