问题描述
项目中创建了一个继承自Control的自定义控件,名为"MyControl",并且创建了一个依赖项属性Value和一个冒泡路由事件ValueChanged事件。下面是使用MyControl的结构:<Gridlocal:MyControl.ValueChanged="grid_ValueChanged"><local:MyControl/><local:MyControl/><local:MyControl/></Grid>我的问题是,既然MyControl的ValueChanged事件被定义为冒泡型的路由事件,在Grid中使用附件事件响应ValueChanged事件,为什么行不通呢?如此而来,定义成冒泡事件有何意义呢?
解决方案
解决方案二:
求解.......
解决方案三:
你想它怎么冒泡?Grid上面就没有相同事件给它冒泡,冒泡必须是有相同事件才能做到,同时必须将事件定义为路由事件,且策略为RoutingStrategy.Bubble。我这里既看不到你事件的定义,不知道是否正确,又没看到外部有相同事件的控件来接收这样的冒泡事件,根本冒不起来嘛。
解决方案四:
引用2楼qldsrx的回复:
你想它怎么冒泡?Grid上面就没有相同事件给它冒泡,冒泡必须是有相同事件才能做到,同时必须将事件定义为路由事件,且策略为RoutingStrategy.Bubble。我这里既看不到你事件的定义,不知道是否正确,又没看到外部有相同事件的控件来接收这样的冒泡事件,根本冒不起来嘛。
1:首先,我的路由事件是定义为RoutingStrategy.Bubble的(由于篇幅有限,这里就没有列代码)。2:其次,Grid没有相同事件给它冒泡,可不可以使用附加事件呢?Grid没有Click事件,但同样可以使用Button.Click响应Click事件。3:如果凡事都要外部有相同的事件才能冒泡,那么,就一定是预定义的事件了吧,自定义的路由事件外部怎么会有呢?
解决方案五:
有人知道吗?
解决方案六:
你先试试你的事件是否能正常工作,也就是将事件处理函数设置到MyControl上面,我不知道你的MyControl是如何定义出来的,自然无法模仿,我也没那么多时间来写控件测试。如果仅仅要引发内部控件的事件,这应该是可以的,但是这个事件需要内部控件值真的发生了改变,内部事件本身能触发才行,你现在只在外部注册了附件事件,内部没有注册,无法知道内部事件是否触发了,问题说不定是内部事件本身就没有引发而不是无法冒泡。
解决方案七:
引用5楼qldsrx的回复:
你先试试你的事件是否能正常工作,也就是将事件处理函数设置到MyControl上面,我不知道你的MyControl是如何定义出来的,自然无法模仿,我也没那么多时间来写控件测试。如果仅仅要引发内部控件的事件,这应该是可以的,但是这个事件需要内部控件值真的发生了改变,内部事件本身能触发才行,你现在只在外部注册了附件事件,内部没有注册,无法知道内部事件是否触发了,问题说不定是内部事件本身就没有引发而不是无法冒泡。
将事件处理函数设置到MyControl上,是能够正常工作的
解决方案八:
有人知道吗?
解决方案九:
有人知道吗?
解决方案十:
引用5楼qldsrx的回复:
我不知道你的MyControl是如何定义出来的,自然无法模仿,我也没那么多时间来写控件测试。
自定义控件:<ResourceDictionaryxmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:local="clr-namespace:WPF3"><StyleTargetType="{x:Typelocal:MyControl}"><SetterProperty="Height"Value="20"/><SetterProperty="Width"Value="30"/><SetterProperty="Template"><Setter.Value><ControlTemplateTargetType="{x:Typelocal:MyControl}"><BorderBackground="Red"BorderThickness="1"BorderBrush="Black"/></ControlTemplate></Setter.Value></Setter></Style></ResourceDictionary>
publicclassMyControl:Control{staticMyControl(){DefaultStyleKeyProperty.OverrideMetadata(typeof(MyControl),newFrameworkPropertyMetadata(typeof(MyControl)));}//依赖项属性publicstaticreadonlyDependencyPropertyValueProperty=DependencyProperty.Register("Value",typeof(double),typeof(MyControl),newFrameworkPropertyMetadata(0,newPropertyChangedCallback(OnValueChanged)));publicdoubleValue{get{return(double)GetValue(ValueProperty);}set{SetValue(ValueProperty,value);}}privatestaticvoidOnValueChanged(DependencyObjectobj,DependencyPropertyChangedEventArgsargs){MyControlcontrol=(MyControl)obj;RoutedPropertyChangedEventArgs<double>e=newRoutedPropertyChangedEventArgs<double>((double)args.OldValue,(double)args.NewValue,ValueChangedEvent);control.OnnnnValueChanged(e);}//路由事件publicstaticreadonlyRoutedEventValueChangedEvent=EventManager.RegisterRoutedEvent("ValueChanged",RoutingStrategy.Bubble,typeof(RoutedPropertyChangedEventHandler<double>),typeof(MyControl));//publiceventRoutedPropertyChangedEventHandler<double>ValueChanged{add{AddHandler(ValueChangedEvent,value);}remove{RemoveHandler(ValueChangedEvent,value);}}protectedvirtualvoidOnnnnValueChanged(RoutedPropertyChangedEventArgs<double>args){RaiseEvent(args);}}
主窗体:<Windowx:Class="WPF3.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:local="clr-namespace:WPF3"Title="MainWindow"Height="350"Width="525"><Gridlocal:MyControl.ValueChanged="grid_ValueChanged"><local:MyControl/><local:MyControl/><local:MyControl/></Grid></Window>
全部的代码就是上面的那些。自定义MyControl中有一个依赖项属性Value,一个路由事件ValueChanged。在主窗体中,Grid里面放了三个MyControl元素,我就想在Grid中集中处理ValueChanged事件。由于Grid并没有ValueChanged事件,所以,在Grid中采用MyControl.ValueChanged附加事件的方式为什么又不行呢?如果都还不行,那此处的路由事件到底路由没有呢?
解决方案十一:
自定义路由事件,真的能路由吗?
解决方案十二:
求高人啊............
解决方案十三:
引用10楼u012945796的回复:
自定义路由事件,真的能路由吗?
当然可以。控件声明这个事件,在合适的时候触发。
解决方案十四:
引用12楼hbu_pig的回复:
Quote: 引用10楼u012945796的回复:
自定义路由事件,真的能路由吗?当然可以。控件声明这个事件,在合适的时候触发。
那你看下我9楼的代码,在Grid中如何处理其子元素的自定义的路由事件呢?
解决方案十五:
有谁知道吗?
解决方案:
在线求解..............
解决方案:
解决方案:
解决方案:
解决方案:
解决方案:
顶上去.............
解决方案:
我也遇到这个问题,搜索的时候看到你的帖子,也不知道你解决没有。后来我看到一个替代方案,调用一下AddHandle,用法大概如下:AddHandle(MyControl.ValueChanged,newRoutedEventHandler(grid_ValueChanged)),相当于做一下订阅。