首页 新闻 会员 周边 捐助

求助!#WPF Binging问题# WPF 绑定 RotateTransform 控制图片旋转角度!

0
悬赏园豆:20 [待解决问题]

  前景:本人大四毕业党一枚,毕业设计导师要求做一个可以控制图片旋转的桌面程序,用的是WPF....但本人学的是Java,WPF表示没怎么接触过,最近遇到一个棘手的问题,调了两天了,也没有调好,所以特来求助! 

    Ok,话不多说,上代码!

这是我的窗体代码(只是一个Demo):

<Window x:Class="ImageRotate.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="testCanvs" Height="280" Width="490" Background="AliceBlue"></Canvas>
    -->
    <Image Name="myG" Height="200" Width="200"  Source="Picture\frontView.png">
        <Image.RenderTransform>
            <RotateTransform Angle="{Binding Path=Angle}" CenterX="100" CenterY="100" />
        </Image.RenderTransform>
    </Image>
</Window>

 

 

后台用的C#,是这样的:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
using ImageRotate;
namespace ImageRotate
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        Image images;
        Test test;
        float a = 0.0f;
        Test t = new Test();
        public MainWindow()
        {
            InitializeComponent();
            //ImageRotate();
            DispatcherTimer dispatcher = new DispatcherTimer();
            dispatcher.Tick += new EventHandler(dispatcherTimer);
            dispatcher.Interval = TimeSpan.FromMilliseconds(1000);
            dispatcher.Start();
            t.Angle = a;
            Binding bin = new Binding();
            bin.Source = t;
            bin.Path = new PropertyPath("Angle");
            RotateTransform rt = new RotateTransform();
            BindingOperations.SetBinding(rt, RotateTransform.AngleProperty, bin);
        }

        private void dispatcherTimer(object sender, EventArgs e)
        {
            Console.Write(" "+a);
            a =a+ 0.2f;
        }

        /**
        private void ImageRotate()
        {
            images = new Image();
            images.Width = 150;
            images.Height = 150;
            TransformedBitmap tb = new TransformedBitmap();
            BitmapImage bi = new BitmapImage();

            bi.BeginInit();
            bi.UriSource = new Uri(@"Picture\frontView.png", UriKind.RelativeOrAbsolute);
            bi.EndInit();

            tb.BeginInit();
            tb.Source = bi;
            

            RotateTransform tramforms = new RotateTransform(45);
            tb.Transform = tramforms;
            tb.EndInit();

            images.Source = tb;
        }
        */
    }
}
    

 还有一个Test的类如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;
using System.Windows.DependencyProperty;
namespace ImageRotate
{
    
    class Test :INotifyPropertyChanged
    {

        public event PropertyChangedEventHandler PropertyChanged;
        
        double _Angle;
        public double Angle
        {
            get { return _Angle; }
            set 
            { 
                _Angle = value;
                 //这里就是报错的地方!
                PropertyChanged.Invoke(this, new PropertyChangedEventArgs("Angle"));
            }
        }

        
    }
    
}

 

每次运行的时候就是报错!

 

 

求助啊!各路大牛,各路神仙们!小弟感激不尽!!!!!

痞小张的主页 痞小张 | 初学一级 | 园豆:166
提问于:2016-03-18 23:06
< >
分享
所有回答(1)
0

试了一下你的代码,这个错误的原因是出在如下地方

PropertyChanged.Invoke(this, new PropertyChangedEventArgs("Angle"));

使用事件前没有判空,当前事件没有订阅的时候就抛出了空引用异常,正确的方式是

    if (PropertyChanged != null)
        PropertyChanged.Invoke(this, new PropertyChangedEventArgs("Angle"));

但是,即使这么写,只是不抛异常而已,你的程序本身就有很多地方有遗漏,简单的修改了一下,你可以参考下:

        public MainWindow()
        {
            InitializeComponent();

            //ImageRotate();
            DispatcherTimer dispatcher = new DispatcherTimer();
            dispatcher.Tick += new EventHandler(dispatcherTimer);
            dispatcher.Interval = TimeSpan.FromMilliseconds(1000);
            dispatcher.Start();
            t.Angle = a;
            Binding bin = new Binding();
            bin.Source = t;
            bin.Path = new PropertyPath("Angle");
            RotateTransform rt = new RotateTransform();
            BindingOperations.SetBinding(rt, RotateTransform.AngleProperty, bin);

            myG.RenderTransform = rt;            //没有应用该Transfrorm
        }

        private void dispatcherTimer(object sender, EventArgs e)
        {
            Console.Write(" " + a);
            a = a + 10f;

            t.Angle = a;                        //没有更新Angle值
        }

        Image images;
        Test test;
        float a = 0.0f;
        Test t = new Test();
    }

    class Test : INotifyPropertyChanged
    {

        public event PropertyChangedEventHandler PropertyChanged;

        double _Angle;
        public double Angle
        {
            get { return _Angle; }
            set
            {
                _Angle = value;
                //这里就是报错的地方!

                if (PropertyChanged != null)            //没有判断是否订阅了事件
                    PropertyChanged.Invoke(this, new PropertyChangedEventArgs("Angle"));
            }
        }
    }

最后说明的是,如果你是要做动画效果的话,这种方式是不正确的,应该使用DoubleAnimation。 当然,你也可以简单的将你现在的代码中的Timer的间隔调整到100ms来实现类似的效果。

 

天方 | 园豆:5407 (大侠五级) | 2016-03-19 08:34
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册