我正在学习WPF/Silverlight并在MS视频播放中看到现在建议使用RoutedEventArgs它EventArgs; 虽然它没有说明原因.
我有一个win表单应用程序,它使用"小部件"的接口,试图不依赖于特定的显示技术(在Presenters/ViewModels中),所以如果我的IButton Click事件现在需要采取RoutedEventArgs现在我想它不是有用.
有人可以解释我是否应该切换到RoutedEventArgs所有情况,为什么?
顺便说一句,其他人是否有关于使用界面小部件的经验/意见,因为我正在描述它们?
我的场景,简化:我有一个包含Employees行的ListView,在每个Employee行中,有一些按钮"Increase"和"Decrease"调整他的工资.
假设在我的程序中,双击Employee行意味着"解雇此人".
该问题是,当我点击"增加"迅速,这将触发对ListViewItem的双击事件.当然,当我只是增加薪水时,我不想解雇员工.
根据所有其他事件的工作原理,我希望能够通过设置Handled=true事件来解决这个问题.但是,这不起作用.在我看来,WPF生成两个独立的,完全未链接的双击事件.
以下是重现我的问题的最小示例.可见组件:
<ListView>
<ListViewItem MouseDoubleClick="ListViewItem_MouseDoubleClick">
<Button MouseDoubleClick="Button_MouseDoubleClick"/>
</ListViewItem>
</ListView>
Run Code Online (Sandbox Code Playgroud)
和处理程序代码:
private void Button_MouseDoubleClick(object s, MouseButtonEventArgs e) {
if (!e.Handled) MessageBox.Show("Button got unhandled doubleclick.");
e.Handled = true;
}
private void ListViewItem_MouseDoubleClick(object s, MouseButtonEventArgs e) {
if (!e.Handled) MessageBox.Show("ListViewItem got unhandled doubleclick.");
e.Handled = true;
}
Run Code Online (Sandbox Code Playgroud)
启动此程序并双击列出的按钮后,两个消息框按顺序显示.(此外,此后按钮会卡在向下位置.)
作为一个"修复",我可以在ListViewItem处理程序上检查附加到事件的可视树,并检查"那里有一个按钮",从而丢弃事件,但这是最后的手段.我想在编码这样一个kludge之前至少理解这个问题.
有谁知道为什么 WPF会这样做,以及一种优雅的惯用方法来避免这个问题?
我正在尝试使用caliburn micro消息来触发我创建的附加事件:
public static class DataChanging
{
public delegate void DataChangingEventHandler(object sender, DataChangingEventArgs e);
public static readonly RoutedEvent ChangingEvent =
EventManager.RegisterRoutedEvent("Changing",
RoutingStrategy.Bubble,
typeof(DataChangingEventHandler),
typeof(DataChanging));
public static void AddChangingHandler(DependencyObject o, DataChangingEventHandler handler)
{
((UIElement)o).AddHandler(DataChanging.ChangingEvent, handler);
}
public static void RemoveChangingHandler(DependencyObject o, DataChangingEventHandler handler)
{
((UIElement)o).RemoveHandler(DataChanging.ChangingEvent, handler);
}
public static bool GetActivationMode(DependencyObject obj)
{
return (bool)obj.GetValue(ActivationModeProperty);
}
public static void SetActivationMode(DependencyObject obj, bool value)
{
obj.SetValue(ActivationModeProperty, value);
}
public static readonly DependencyProperty ActivationModeProperty =
DependencyProperty.RegisterAttached("ActivationMode",
typeof(bool),
typeof(DataChanging),
new FrameworkPropertyMetadata(false,
HandleActivationModeChanged));
private static …Run Code Online (Sandbox Code Playgroud) 我想知道是否有办法观察WPF应用程序中引发的所有RoutedEvent.写一些关于向控制台发起的事件的信息的方法将是完美的,看看发生了什么.
在我的用户控件中,我有一个按钮,单击该按钮将引发自定义路由事件.我试图提高它,但它不会在MainWindow.xaml中被触发.
用户控件中按钮的Xaml:
<Button x:Name="PART_Add" Content="+" Grid.Column="3" Margin="0,0,0,0" Style="{DynamicResource dTranspButton}" Click="btnAdd_Click"/>
Run Code Online (Sandbox Code Playgroud)
UserControl C#代码:
//AddClick Event
public static readonly RoutedEvent AddClickEvent = EventManager.RegisterRoutedEvent("AddClick", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(dCB_Props));
public event RoutedEventHandler AddClick
{
add { AddHandler(AddClickEvent, value); }
remove { RemoveHandler(AddClickEvent, value); }
}
void RaiseAddClickEvent()
{
RoutedEventArgs newEventArgs = new RoutedEventArgs(dCB_Props.AddClickEvent);
}
protected void OnAddClick()
{
RaiseAddClickEvent();
}
//objects events
private void btnAdd_Click(object sender, System.Windows.RoutedEventArgs e)
{
RaiseAddClickEvent();
}
Run Code Online (Sandbox Code Playgroud)
MainWindow.xaml中UserControl实例的Xaml代码:
<local:dCB_Props x:Name="cb1" Margin="41.166,0,36.19,25" VerticalAlignment="Bottom" Height="30" Width="141" AddClick="dCB_Props_AddClick">
<local:dCB_Props.Items>
<ComboBoxItem Content="item1"/>
</local:dCB_Props.Items>
</local:dCB_Props>
Run Code Online (Sandbox Code Playgroud)
应该在MainWindow.xaml.cs中触发的C#代码: …
我跟随XAML
<StackPanel MouseEnter="StackPanel_MouseEnter" Height="130" Background="Blue">
<Grid MouseEnter="Grid_MouseEnter" Height="60" Background="Red" >
<Button MouseEnter="Button_MouseEnter" Height="20"/>
</Grid>
</StackPanel>
Run Code Online (Sandbox Code Playgroud)
在代码背后,我正在这样做
private void StackPanel_MouseEnter(object sender, MouseEventArgs e)
{
}
private void Grid_MouseEnter(object sender, MouseEventArgs e)
{
e.Handled = true;
}
private void Button_MouseEnter(object sender, MouseEventArgs e)
{
e.Handled = true;
}
Run Code Online (Sandbox Code Playgroud)
现在,即使我将鼠标移动Button并设置e.Handled = true,Grid也StackPanel分别调用和调用事件.为什么?我应该怎么做才能阻止路由事件冒泡?
有谁知道为什么我不能在控件模板上设置事件?
例如,以下代码行将无法编译.它通过控件模板中的任何事件执行此操作.
<ControlTemplate x:Key="DefaultTemplate" TargetType="ContentControl">
<StackPanel Loaded="StackPanel_Loaded">
</StackPanel>
</ControlTemplate>
Run Code Online (Sandbox Code Playgroud)
我使用的是MVVM设计模式,此处的控件位于ResourceDictionary中,该ResourceDictionary被添加到应用程序的MergedDictionaries中.
我试图围绕一些WPF特定的东西,并且尚未找到UIElement.AddHandler方法和EventManager.RegisterClassHandler方法之间的具体关系.
我已经google了一下,发现了这篇有趣的MSDN文章:
http://msdn.microsoft.com/en-us/library/ms747183.aspx
这里说明:
"路由事件考虑事件的两种不同类型的侦听器:类侦听器和实例侦听器.类侦听器存在,因为类型在其静态构造函数中调用了特定的EventManager API,RegisterClassHandler,或者从元素库中重写了类处理程序虚方法实例监听器是特定的类实例/元素,其中通过调用AddHandler为该路由事件附加了一个或多个处理程序.
好了,所以我知道一个类和它的实例之间的区别,但不知何故,我无法理解文档的这个特定部分.
任何人都可以为我清楚吗?
在尝试做一些更复杂的事情时,我遇到了一个我不太了解的行为.
假设下面的代码处理textChanged事件.
private void textChanged(object sender, TextChangedEventArgs e)
{
TextBox current = sender as TextBox;
current.Text = current.Text + "+";
}
Run Code Online (Sandbox Code Playgroud)
现在,在文本框中键入一个字符(例如,A)将导致事件被触发两次(添加两个'+'),最终显示的文本只是A +.
我的两个问题是,为什么事件只发生了两次?为什么只有第一次通过事件才能实际设置文本框的文本?
提前致谢!