【问题标题】:Transformation does not work correctly转换无法正常工作
【发布时间】:2013-09-07 20:10:18
【问题描述】:

这是我的旋转对象的代码。我必须旋转两个相同类型的对象。

初始化:

private TransformGroup trGrp;
        private RotateTransform trRot;
        private TransformGroup trGrp1;
        private RotateTransform trRot1;
        static private double angle;
        SerialPort port;
        value v;
        string result;
        public int zeroValue;
        public MainWindow()
        {
            InitializeComponent();
            angle = 0;
            zeroValue = 327;
            trGrp = new TransformGroup();
            trRot = new RotateTransform(angle) { CenterX = rectangle1.Width / 2, CenterY = rectangle1.Height };
            trGrp1 = new TransformGroup();
            trRot1 = new RotateTransform(angle) { CenterX = rectangle1.Width / 2, CenterY = rectangle1.Height };
           // trGrp.Children.Add(trRot);
            //trGrp1.Children.Add(trRot1);
            v = new value();
            port = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
            port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
            port.Open();
        }

串口接收数据代码:

void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            if (!port.IsOpen)
            { 
                port.Open(); 
            }

            try
            {
                result = port.ReadLine();
                result = result.Replace("\r", "");
            }

            catch (Exception e1)
            { MessageBox.Show(e1.Message); }
            int[] temp = new int[4];
            this.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Background,
        new Action(
          delegate()
          {


              try
              {

                      temp[0] = int.Parse(result[1].ToString() + result[2].ToString() + result[3].ToString() + result[4].ToString());

                      if (temp[0] == zeroValue)
                      {

                          trRot.Angle = 0;
                          trGrp.Children.Add(trRot);
                          rectangle1.RenderTransform = trGrp;
                          trGrp.Children.RemoveAt(0);//because Add function adds a new trGrp so its size increases and we do not need old trGrp so we remove them.
                          label3.Content = trRot.Angle.ToString();

                      }

                      else if (temp[0] > zeroValue)
                      {

                          int totalValues = temp[0] - zeroValue;
                          if (totalValues == 1) 
                          {
                              totalValues = 0;
                          }
                          textBox3.Text = temp[0].ToString();
                          angle = totalValues * Properties.Settings.Default.angle;

                          if (angle<31)
                          {
                              trRot.Angle = angle / 2;
                              trGrp.Children.Add(trRot);
                              rectangle1.RenderTransform = trGrp;
                              //trGrp.Children.RemoveAt(1);//because Add function adds a new trGrp so its size increases and we do not need old trGrp so we remove them.
                              trGrp.Children.Remove(trRot);
                              label3.Content = angle.ToString();
                          }




                      }
                      else if (temp[0] < zeroValue)
                      {

                          int totalValues = zeroValue - temp[0];
                          if (totalValues==1)
                          {
                              totalValues = 0;
                          }
                          textBox3.Text = temp[0].ToString();
                          angle = -totalValues * Properties.Settings.Default.angle;

                          if (angle> -21)
                          {
                              trRot.Angle = angle / 2;
                          trGrp.Children.Add(trRot);
                          rectangle1.RenderTransform = trGrp;
                          trGrp.Children.Remove(trRot);//because Add function adds a new trGrp so its size increases and we do not need old trGrp so we remove them.
                          label3.Content = angle.ToString();
                          }




                      }

              }
              catch (Exception)
              { }
          }
      ));
            this.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Background,
        new Action(
          delegate()
          {

              try
              {
                  temp[1] = int.Parse(result[6].ToString() + result[7].ToString() + result[8].ToString() + result[9].ToString());
                  if (temp[1] == zeroValue)
                  {

                      trRot1.Angle = 0;
                      trGrp.Children.Add(trRot1);
                      rectangle2.RenderTransform = trGrp1;
                      trGrp1.Children.RemoveAt(1);//because Add function adds a new trGrp so its size increases and we do not need old trGrp so we remove them.
                      // textBox3.Text = trRot.Angle.ToString();
                      label4.Content = angle.ToString();

                  }

                  else if (temp[1] > zeroValue)
                  {

                      int totalValues = temp[1] - zeroValue;
                      if (totalValues == 1)
                      {
                          totalValues = 0;
                      }
                      angle = totalValues * Properties.Settings.Default.angle;
                      angle = Math.Round(angle, 0);
                      if (angle < 21)
                      {
                          trRot1.Angle = angle / 2;
                          trGrp1.Children.Add(trRot1);
                          rectangle2.RenderTransform = trGrp1;
                          trGrp1.Children.RemoveAt(0);//because Add function adds a new trGrp so its size increases and we do not need old trGrp so we remove them.
                          label4.Content = angle.ToString();
                      }
                  }
                  else if (temp[1] < zeroValue)
                  {

                      int totalValues = zeroValue - temp[1];
                      if (totalValues == 1)
                      {
                          totalValues = 0;
                      }
                      angle = -totalValues * Properties.Settings.Default.angle;

                      if (angle > -21)
                      {
                          trRot1.Angle = angle / 2;
                          trGrp1.Children.Add(trRot1);
                          rectangle2.RenderTransform = trGrp1;
                          trGrp1.Children.RemoveAt(0);//because Add function adds a new trGrp so its size increases and we do not need old trGrp so we remove them.
                          label4.Content = angle.ToString();
                      }


                  }
              }
              catch (Exception)
              {


              }
          }));


        }

我在这里使用了两个 Dispatcher.BeginInvok 函数,因为我想同时旋转两个对象。但问题是,当我只使用一个对象来旋转时,就没有问题了。但是当我包含第二个对象时,第一个对象不会根据我在程序中提到的角度正确旋转。我的理解是,每次触发事件时,transformGroup 添加一个新的rotateTransform 是一个问题。所以我尝试在添加后删除添加的 TrRot。但这对我也不起作用。 谢谢。

【问题讨论】:

  • 为什么不直接在 XAML 中添加动画?此外,使用Dispatcher.Invoke 是否意味着您的代码将并行运行...它只是将您的请求添加到主 UI 线程队列中,就像您在 XAML 中添加两个动画一样。
  • 会有不同的结果吗?我必须为收到的串行端口数据编写事件处理程序,这就是我在那里写它的原因。

标签: wpf transformation rotatetransform transformgroup


【解决方案1】:

您可以添加一个简单的 Trigger 以在 XAML 中启动动画...假设您添加了一个名为 IsReadybool 属性。然后,您可以在将其设置为 true 时触发动画,并在将其设置为 false 时停止动画。将此Style 添加到包含需要动画的RotateTransform 对象的任何对象中:

<Style>
    <Style.Triggers>
        <DataTrigger Binding="{Binding IsReady}" Value="True">
            <DataTrigger.EnterActions>
                <BeginStoryboard>
                    <Storyboard RepeatBehavior="Forever">
                        <DoubleAnimation Storyboard.TargetProperty="RenderTransform.
(RotateTransform.Angle)" From="0" To="359" Duration="0:0:1" />
                    </Storyboard>
                </BeginStoryboard>
            </DataTrigger.EnterActions>
        </DataTrigger>
    </Style.Triggers>
</Style>

【讨论】: