none
如何应对此问题?Cannot find governing FrameworkElement or FrameworkContentElement for target element RRS feed

  • 问题

  • 整体意图是使用TriggerCollecion的附加属性获取对象,附加值为EventTrigger,且具有依赖属性,通过TriggerCollection传递附加对象。在EventTrigger上写入事件名称,同时通过反射引发事件,再通过EventTrigger具有的依赖属性,值为TriggerFace,向其他类传递事件的引发结果。

    一直到这里都是可以正常工作的。

    但是我将继承TriggerFace的类,编写依赖属性且进行绑定时,就会报错。仿佛这个属性不存在一样。

    我应该怎么改进错误?

    或者说 这个错误是怎么来的?

    是我的思路有问题吗?


     class TriggerCollection
        {
            public static readonly DependencyProperty TriggersValueProperty = DependencyProperty.RegisterAttached("TriggersValue", typeof(EventTrigger), typeof(TriggerActionCollection), new PropertyMetadata(new PropertyChangedCallback(OnValueChanged)));
    
            public static EventTrigger GetTriggersValue(DependencyObject d) => d.GetValue(TriggersValueProperty) as EventTrigger;
            public static void SetTriggersValue(DependencyObject d, EventTrigger value) => d.SetValue(TriggersValueProperty, value);
    
            private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                (e.NewValue as ITriggerTarget).Target = d;
    
            }
        }
        [ContentProperty("Event")]
        class EventTrigger : DependencyObject, ITriggerTarget
        {
            public static readonly DependencyProperty EventProperty = DependencyProperty.Register("Event", typeof(TriggerFace), typeof(EventTrigger), new PropertyMetadata(new PropertyChangedCallback(CallBack)));
            public TriggerFace Event
            {
                get => GetValue(EventProperty) as TriggerFace;
                set => SetValue(EventProperty, value);
            }
            private static void CallBack(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                trigger = e.NewValue as ITriggerBase;
                
            }
            private static ITriggerBase trigger;
            public string EventName
            {
                get;
                set;
            }
            private DependencyObject _target = new DependencyObject();
            public DependencyObject Target
            {
                get => _target;
                set
                {
                    _target = value;
    
                    OnGetValue(Target);
                }
            }
            private void OnGetValue(DependencyObject d)
            {
                var source = Activator.CreateInstance(Target.GetType()).GetType();
                var mothod = source.GetEvent(EventName);
                var local = this.GetType().GetMethod(nameof(EventMethod), System.Reflection.BindingFlags.NonPublic | BindingFlags.Instance);
    
                var dgle = Delegate.CreateDelegate(mothod.EventHandlerType, this, local);
                mothod.AddEventHandler(Target, dgle);
            }
            private void EventMethod(object sender, EventArgs e)
            {
                (trigger as ITriggerTarget).Target = Target;
                trigger.Invoke(e);
            }
    
    
        }
        interface ITriggerTarget
        {
            DependencyObject Target
            {
                get;
                set;
            }
        }
        interface ITriggerBase : ITriggerTarget
        {
    
            void Invoke(object parameter);
        }
        abstract class TriggerFace : DependencyObject, ITriggerTarget, ITriggerBase
        {
      
            public DependencyObject Target { get; set; }
    
            public abstract void Invoke(object parameter);
        }
        class CommandTrigger :  TriggerFace 
        {
            public override void Invoke(object parameter)
            {
    
             
                 
            }
    
            
            public static readonly DependencyProperty CommandProperty = DependencyProperty.Register("Command", typeof(ICommand), typeof(CommandTrigger), new PropertyMetadata(new PropertyChangedCallback(CallBack)));
    
            private static void CallBack(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
    
            }
    
            public ICommand Command
            {
                get => GetValue(CommandProperty) as ICommand;
                set => SetValue(CommandProperty, value);
            }
          
        }


     class EventCommandBase : ICommand
        {
            private Action<object, EventArgs> DoAction;
            private Func<object, bool> CanAction;
            public event EventHandler CanExecuteChanged;
    
            public EventCommandBase(Action<object, EventArgs> ac, Func<object, bool> fc)
            {
                this.DoAction = ac;
                this.CanAction = fc;
            }
            public bool CanExecute(object parameter)
            {
                return CanAction.Invoke(parameter);
            }
    
            public void Execute(object parameter)
            {
                var b = parameter is object[];
                if (b)
                    DoAction.Invoke((parameter as object[])[0], (EventArgs)(parameter as object[])[1]);
                else
                    DoAction?.Invoke(null, (EventArgs)parameter);
            }
        }
        class DO : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
            public DO()
            {
    
            }
    
            private bool CanDoAcion(object arg)
            {
                return true;
            }
    
            private void DoAcion(object arg1, EventArgs arg2)
            {
                throw new NotImplementedException();
            }
    
            public ICommand  SizeChanged => new EventCommandBase(new Action<object, EventArgs>(DoAcion), new Func<object, bool>(CanDoAcion));
        }

    <Window.DataContext>
            <local:DO/>
        </Window.DataContext>
        <Grid  >
            <local:TriggerCollection.TriggersValue>
                <local:EventTrigger EventName="SizeChanged">
                    <local:CommandTrigger   Command="{Binding  ElementName=sc, Path=DataContext.SizeChanged }"/>
                </local:EventTrigger>
            </local:TriggerCollection.TriggersValue>
        </Grid>






    • 已编辑 ARM830 2020年3月15日 2:16
    2020年3月15日 2:09

答案

  • 自己回答吧,

    应该是xaml的问题,不过可以使用freezablecollection集合避免此问题。

    让eventtrigger继承Freezablecollection,其他子类继承Animatable就好了

    • 已标记为答案 ARM830 2020年3月29日 13:32
    2020年3月29日 13:30

全部回复

  • Hi,

    运行你的代码没有报错,是哪里在报错?

    Best Regards,

    Alex


    "Windows Presentation Foundation" forum will be migrating to a new home on Microsoft Q&A (Preview)!
    We invite you to post new questions in the "Developing Universal Windows apps" forum’s new home on Microsoft Q&A (Preview)!
    For more information, please refer to the sticky post.

    2020年3月17日 9:37
  •  绑定好,Invoke事件是可以触发的,但是依赖属性的command是没有办法获取或者触发的。绑定没有相应

    你是可以触发吗?

    <Window.DataContext>
            <local:DO x:Key="sc"/>
        </Window.DataContext>
        <Grid  >
            <local:TriggerCollection.TriggersValue>
                <local:EventTrigger EventName="SizeChanged">
                    <local:CommandTrigger   Command="{Binding  ElementName=sc, Path=DataContext.SizeChanged }"/>
                </local:EventTrigger>
            </local:TriggerCollection.TriggersValue>
        </Grid>



    • 已编辑 ARM830 2020年3月17日 13:27
    2020年3月17日 12:39
  • 自己回答吧,

    应该是xaml的问题,不过可以使用freezablecollection集合避免此问题。

    让eventtrigger继承Freezablecollection,其他子类继承Animatable就好了

    • 已标记为答案 ARM830 2020年3月29日 13:32
    2020年3月29日 13:30