对WPF控件派生类的非WPF实例回调.更改DependencyProperty


  1. WPF控件派生类包含非WPF控件衍生类nner,应该触发Outer类WPF DependencyProperty的更改。

  2. 本质不变是我的内部类不应强制任何WPF命名空间使用,因此,是我正在创建的dll的API的一部分。因此,从任何WPF类继承都不是合适的解决方案。

实现从非.NET派生类到WPF控件类的回调以更改DependencyProperty对象的最佳(或至少是仲裁(方法是什么

发现了一些假设的回调机制:

  • c#委派和c#事件

无法解决此问题,因为它引发了运行时异常

The calling thread cannot access this object because a different thread owns it.

当回调机制试图修改Background属性时(我认为DependencyProperty对象是键,或者至少是.NET定义的属性(。

我想c#委托不能以单线程方式工作——然而,我在阅读c#文档时没有发现这一事实。

(一种解决方案是通过.NET Dispatcher类和Invoke((,但它似乎太武断了,而且可能很慢——难道没有更适合WPF的方法吗?(

  • 我读过关于路由事件和DependencyProperties的文章

在WPF文档中(但是还没有测试过(,但Routed事件似乎没有帮助(因为我的Inner类不是VisualTree的一部分(,我不应该从DependencyObject继承。

我读了(我想(所有与我的问题有关的东西。如果有人问我类似的问题,我很抱歉,如果问题的本质是一样的,如果你能把我引向那个话题,我会很高兴。

简化示例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows.Media;
using System.Timers;
namespace WpfApplication4
{
    internal class Rect:ContentControl
    {
        Inner inner = new Inner();
        public Rect()
        {
            inner.Rotate += new Inner.RotateEventHandler(rotated);
        }
        public void rotated(object sender, RotateEventArgs args)
        {
            Background = Brushes.Blue;                            //Run time error
            VisualTransform = new RotateTransform(args.Angle);  //Run time error
        }
    }
    public class Inner
    {
        Timer timer = new Timer(200);
        public Inner()
        {
            timer.Enabled = true;
            timer.Elapsed +=new ElapsedEventHandler(elapsed);
        }
        public delegate void RotateEventHandler(object sender, RotateEventArgs args);
        public event RotateEventHandler Rotate;
        public void elapsed(object sender, ElapsedEventArgs e)
        {
            RotateEventArgs args = new RotateEventArgs();
            args.Angle = args.Angle + 45;
            OnRotate(args);
        }
        protected void OnRotate(RotateEventArgs e)
        {
            if (e != null)
            {
                Rotate(this, e);
            }
        }
    }
    internal class RotateEventArgs
    {
        private double angle = 0;
        public double Angle
        {
            set { angle = value; }
            get { return angle; }
        }
    }
}

您可以使用DispatchTimer而不是Timer。在Rect类本身中具有DispatchTimer

最新更新