none
用Action<DependencyObject>类型的附加属性在xaml绑定静态的Action<DependencyProperty>字段,运行就出错,怎么解决? RRS feed

  • 问题

  •       class TestClass
          {
      public static Action<DependencyObject> GetShrinkAction(DependencyObject obj)
            {
                return (Action<DependencyObject>)obj.GetValue(ShrinkActionProperty);
            }
    
            public static void SetShrinkAction(DependencyObject obj, Action<DependencyObject> value)
            {
                obj.SetValue(ShrinkActionProperty, value);
            }
    
            
            public static readonly DependencyProperty ShrinkActionProperty =
                DependencyProperty.RegisterAttached("ShrinkAction", typeof(Action<DependencyObject>), typeof(TestClass));
    
    public static Action<DependencyProperty> TestCloseAction = new Action<DependencyProperty>(close);
    
            public static void close(DependencyProperty dp)
            {
                MessageBox.Show("dp");
            }
    }

    c#代码 

    c:TestClass.ShrinkAction="{x:Static c:TestClass.TestCloseAction}"

    xaml代码部分 

    我想要附加自己的自定义事件到控件上,这个事件是在另一个附加属性中的值被修改时的回调方法内被引发,但是附加属性是静态的,所以不行。

    所以次要点,考虑委托类型的附加属性来模仿附加自定义事件到控件的方法。上面的委托类型的附加属性,是在另一个附加属性中的值被修改时的回调方法内被调用(如果这个委托类型的附加属性不为null的话),在c#设置,没有出错,运行也没有出问题,但在如上面的xaml上使用绑定静态方法的模式,绑定一个静态的Action<DependencyObject>字段,没有提示错误。但是运行时就出错了,错误内容为

    “System.Windows.Markup.XamlParseException:“内部异常ArgumentException: “System.Action`1[System.Windows.DependencyProperty]”不是属性“ShrinkAction”的有效值。

    这个语法不对么?怎么解决?


    • 已编辑 Trian555 2019年2月27日 7:16
    2019年2月27日 7:14

答案

  • 如果是自定义事件

    请参考:

    附加事件

    博客

    附加事件

    这里面说一下 非Ulement派生的类是无法引发附加事件的。只有在CS页面添加监视或者在其它事件中引发附加事件。

    所以最好的解决办法是在Ulement派生的类中添加附加事件。

    个人理解:非Ulement派生的附加事件多半是P用没有的,除非是这个类是关联到一些事务处理。即便是Ulement派生多半也是无用功大于你想要的效果

    给你小栗子:

    附加事件页面

    public   class NR
        {
            public bool TestProperty { get; set; }
    
    
            public static readonly RoutedEvent TestEvent = EventManager.RegisterRoutedEvent("Test", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(NR));
            public static void AddTestEventHandler(DependencyObject d, RoutedEventHandler handler)
            {
                var u = d as UIElement;
                if (u != null)
                {
                    
                    u.AddHandler(NR.TestEvent, handler);
                }
            }
            public static void RemoveTestEventHandler(DependencyObject d, RoutedEventHandler handler)
            {
                var u = d as UIElement;
                if (u != null)
                {
                    u.RemoveHandler(NR.TestEvent, handler);
                }
            }
            }

    xaml

        <Grid>
            <Button Click="Button_Click"  Visibility="Visible" Margin="344,119,357,240"/>
        </Grid>


    cs页面

        public partial class MainWindow : Window
        {
            NR NewNRTest;
            public MainWindow()
            {
                InitializeComponent();
                NewNRTest = new NR
                {
                    TestProperty = false
                };
                NR.AddTestEventHandler(this, new RoutedEventHandler(TestMenth));
            }
    
            private void TestMenth(object sender, RoutedEventArgs e)
            {
                MessageBox.Show((e.OriginalSource as NR).TestProperty.ToString());
           
            }
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                NewNRTest.TestProperty = true;
                RoutedEventArgs arg = new RoutedEventArgs(NR.TestEvent,NewNRTest);
                this.RaiseEvent(arg);
            }
        }


    • 已编辑 ARM830 2019年2月27日 11:22
    • 已标记为答案 Trian555 2019年3月2日 11:34
    2019年2月27日 11:10
  • 有个简单的办法,换掉委托参数类型,把Action<DependencyObject>换成Action<FrameworkElement>或Action<object>,就能运行不出错,在xaml上也能绑定静态的和ViewModel对象里的Action<FrameworkElement>或Action<Object>委托字段,获取也能调用。不过在ViewModel里建议最好用Command
    2019年2月28日 2:15
  • 我想要附加自己的自定义事件到控件上,这个事件是在另一个附加属性中的值被修改时的回调方法内被引发,但是附加属性是静态的,所以不行。

    所以次要点,考虑委托类型的附加属性来模仿附加自定义事件到控件的方法。上面的委托类型的附加属性,是在另一个附加属性中的值被修改时的回调方法内被调用(如果这个委托类型的附加属性不为null的话),在c#设置,没有出错,运行也没有出问题,但在如上面的xaml上使用绑定静态方法的模式,绑定一个静态的Action<DependencyObject>字段,没有提示错误。但是运行时就出错了,错误内容为

    “System.Windows.Markup.XamlParseException:“内部异常ArgumentException: “System.Action`1[System.Windows.DependencyProperty]”不是属性“ShrinkAction”的有效值。

    这个语法不对么?怎么解决?


    Hi Trian555,

    根据你的描述, 有一个附加属性, 你想这个附加属性的值发生改变时, 可以调用一个方法是吗?

    如果是这样的话,我建议你可以使用附加事件来解决这个问题, 下面是一个小的例子, 你可以看一下。

    https://www.cnblogs.com/qq247039968/p/4308775.html

    根据你上面的代码我们可以得出, ShrinkAction是一个委托类型的附加属性,那请问一下TestCloseAction是什么?你是想把一个静态的方法给这个附加属性吗?

    Best Regards,

    Cherry


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • 已标记为答案 Trian555 2019年3月2日 11:34
    2019年2月28日 2:50
    版主

全部回复

  • 如果是自定义事件

    请参考:

    附加事件

    博客

    附加事件

    这里面说一下 非Ulement派生的类是无法引发附加事件的。只有在CS页面添加监视或者在其它事件中引发附加事件。

    所以最好的解决办法是在Ulement派生的类中添加附加事件。

    个人理解:非Ulement派生的附加事件多半是P用没有的,除非是这个类是关联到一些事务处理。即便是Ulement派生多半也是无用功大于你想要的效果

    给你小栗子:

    附加事件页面

    public   class NR
        {
            public bool TestProperty { get; set; }
    
    
            public static readonly RoutedEvent TestEvent = EventManager.RegisterRoutedEvent("Test", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(NR));
            public static void AddTestEventHandler(DependencyObject d, RoutedEventHandler handler)
            {
                var u = d as UIElement;
                if (u != null)
                {
                    
                    u.AddHandler(NR.TestEvent, handler);
                }
            }
            public static void RemoveTestEventHandler(DependencyObject d, RoutedEventHandler handler)
            {
                var u = d as UIElement;
                if (u != null)
                {
                    u.RemoveHandler(NR.TestEvent, handler);
                }
            }
            }

    xaml

        <Grid>
            <Button Click="Button_Click"  Visibility="Visible" Margin="344,119,357,240"/>
        </Grid>


    cs页面

        public partial class MainWindow : Window
        {
            NR NewNRTest;
            public MainWindow()
            {
                InitializeComponent();
                NewNRTest = new NR
                {
                    TestProperty = false
                };
                NR.AddTestEventHandler(this, new RoutedEventHandler(TestMenth));
            }
    
            private void TestMenth(object sender, RoutedEventArgs e)
            {
                MessageBox.Show((e.OriginalSource as NR).TestProperty.ToString());
           
            }
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                NewNRTest.TestProperty = true;
                RoutedEventArgs arg = new RoutedEventArgs(NR.TestEvent,NewNRTest);
                this.RaiseEvent(arg);
            }
        }


    • 已编辑 ARM830 2019年2月27日 11:22
    • 已标记为答案 Trian555 2019年3月2日 11:34
    2019年2月27日 11:10
  • 有个简单的办法,换掉委托参数类型,把Action<DependencyObject>换成Action<FrameworkElement>或Action<object>,就能运行不出错,在xaml上也能绑定静态的和ViewModel对象里的Action<FrameworkElement>或Action<Object>委托字段,获取也能调用。不过在ViewModel里建议最好用Command
    2019年2月28日 2:15
  • 我想要附加自己的自定义事件到控件上,这个事件是在另一个附加属性中的值被修改时的回调方法内被引发,但是附加属性是静态的,所以不行。

    所以次要点,考虑委托类型的附加属性来模仿附加自定义事件到控件的方法。上面的委托类型的附加属性,是在另一个附加属性中的值被修改时的回调方法内被调用(如果这个委托类型的附加属性不为null的话),在c#设置,没有出错,运行也没有出问题,但在如上面的xaml上使用绑定静态方法的模式,绑定一个静态的Action<DependencyObject>字段,没有提示错误。但是运行时就出错了,错误内容为

    “System.Windows.Markup.XamlParseException:“内部异常ArgumentException: “System.Action`1[System.Windows.DependencyProperty]”不是属性“ShrinkAction”的有效值。

    这个语法不对么?怎么解决?


    Hi Trian555,

    根据你的描述, 有一个附加属性, 你想这个附加属性的值发生改变时, 可以调用一个方法是吗?

    如果是这样的话,我建议你可以使用附加事件来解决这个问题, 下面是一个小的例子, 你可以看一下。

    https://www.cnblogs.com/qq247039968/p/4308775.html

    根据你上面的代码我们可以得出, ShrinkAction是一个委托类型的附加属性,那请问一下TestCloseAction是什么?你是想把一个静态的方法给这个附加属性吗?

    Best Regards,

    Cherry


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • 已标记为答案 Trian555 2019年3月2日 11:34
    2019年2月28日 2:50
    版主
  • 我想要附加自己的自定义事件到控件上,这个事件是在另一个附加属性中的值被修改时的回调方法内被引发,但是附加属性是静态的,所以不行。

    所以次要点,考虑委托类型的附加属性来模仿附加自定义事件到控件的方法。上面的委托类型的附加属性,是在另一个附加属性中的值被修改时的回调方法内被调用(如果这个委托类型的附加属性不为null的话),在c#设置,没有出错,运行也没有出问题,但在如上面的xaml上使用绑定静态方法的模式,绑定一个静态的Action<DependencyObject>字段,没有提示错误。但是运行时就出错了,错误内容为

    “System.Windows.Markup.XamlParseException:“内部异常ArgumentException: “System.Action`1[System.Windows.DependencyProperty]”不是属性“ShrinkAction”的有效值。

    这个语法不对么?怎么解决?


    Hi Trian555,

    根据你的描述, 有一个附加属性, 你想这个附加属性的值发生改变时, 可以调用一个方法是吗?

    如果是这样的话,我建议你可以使用附加事件来解决这个问题, 下面是一个小的例子, 你可以看一下。

    https://www.cnblogs.com/qq247039968/p/4308775.html

    根据你上面的代码我们可以得出, ShrinkAction是一个委托类型的附加属性,那请问一下TestCloseAction是什么?你是想把一个静态的方法给这个附加属性吗?

    Best Regards,

    Cherry


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    是的,附加属性内容发生改变时,在回调方法内调用委托里的方法或者引发事件。其置于里面的内容,可以事先不写,如果是事件的话,能在xaml上指定的对象直接指定窗体对象内的事件代码,也能在xaml直接绑定静态内容(静态委托字段或非窗体对象内的静态事件),也能被Command命令所绑定。也能在用c#代码设置,

    TestCloseAction只是一个测试方法,测试绑定静态委托字段时,运行测试是否被调用了


    • 已编辑 Trian555 2019年2月28日 4:14
    2019年2月28日 4:11