WPF 控件坐标绑定-主窗口移动时,子窗口跟随主窗口移动



            工程中常常设计子窗口放在主窗口的指定位置,如图所示。测试窗口是红色,在主窗口的黑色区域(用了一个控件定位,比如Canvas等)。将位置设置好之后,相安无事。

WPF 控件坐标绑定-主窗口移动时,子窗口跟随主窗口移动_第1张图片

      但是将主窗口移动时,子窗口并没有跟着移动,出现如下情况,这并不是设计中期望的。

WPF 控件坐标绑定-主窗口移动时,子窗口跟随主窗口移动_第2张图片

        为了解决这个问题,采用子窗口控件位置绑定的办法。

主窗口中继承INotifyPropertyChanged接口,并定义2个属性性变量分别表示LeftSubWnd和TopSubWnd。

      增加CompositionTarget.Rendering += new EventHandler(WindowPositionChange);来捕捉窗口位置发生的变化,并在相应的回调函数中修改属性变量的值,于是通过双向绑定的控件位置就自然发生变化,达到和主窗口跟随的效果。

代码如下

namespace TestMove
{
    /// 
    /// MainWindow.xaml 的交互逻辑
    /// 
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        TestWnd mTestWnd = new TestWnd();
        Window1 mWindow1 = new Window1();
        //增加属性,子窗口的位置Left
        private double _leftSubWnd =0;
        public double LeftSubWnd
        {
            get
            {
                return _leftSubWnd;
            }
            set
            {
                if (_leftSubWnd != value)
                {
                    _leftSubWnd = value;
                    OnPropertyChanged("LeftSubWnd");
                }
            }
        }

        //增加属性,子窗口的位置Top
        private double _topSubWnd = 0;
        public double TopSubWnd
        {
            get
            {
                return _topSubWnd;
            }
            set
            {
                if (_topSubWnd != value)
                {
                    _topSubWnd = value;
                    OnPropertyChanged("TopSubWnd");
                }
            }
        }

        //重写属性改变
        public event PropertyChangedEventHandler PropertyChanged;
        public virtual void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        //初始化
        public MainWindow()
        {
            InitializeComponent();
            CompositionTarget.Rendering += new EventHandler(WindowPositionChange);
        }

        //位置发生变化
        void WindowPositionChange(object sender, EventArgs e)
        {
            Point temPoint = canvas1.PointToScreen(new Point(0, 0));
            mTestWnd.Owner = this;
            LeftSubWnd = temPoint.X;
            TopSubWnd = temPoint.Y;
        }

        //设置绑定
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            Binding temBindg = new Binding();
            temBindg.Source = this;
            temBindg.Mode = BindingMode.TwoWay;
            temBindg.Path = new PropertyPath("LeftSubWnd");
            mTestWnd.SetBinding(Window.LeftProperty, temBindg);
            mWindow1.SetBinding(Window.LeftProperty, temBindg);

            Binding temBindg2 = new Binding();
            temBindg2.Source = this;
            temBindg2.Mode = BindingMode.TwoWay;
            temBindg2.Path = new PropertyPath("TopSubWnd");
            mTestWnd.SetBinding(Window.TopProperty, temBindg2);
            mWindow1.SetBinding(Window.TopProperty, temBindg2);

            mTestWnd.Owner = this;
            mWindow1.Owner = this;
            mTestWnd.Show();
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            mWindow1.Show();
            mTestWnd.Hide();
        }

        private void button2_Click(object sender, RoutedEventArgs e)
        {
            mTestWnd.Show();
            mWindow1.Hide();
        }
    }
}


       

你可能感兴趣的:(WPF,c#)