- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
编辑:我想我问了一些 XY 问题。我真的不关心让隧道事件正常工作,我关心的是让一个事件从父窗口的代码背后引发,然后被拾取并使用react通过作为该窗口的子控件的控件,无需明确告诉子控件其父控件是谁并手动订阅该事件。
我试图在父控件中引发一个事件,并让子控件监听该事件并对其使用react。根据我的研究,我认为我只需要执行一个 RoutedEvent
但我做错了。
这是一个 MCVE,展示了我的尝试,它是一个简单的程序,里面有一个窗口和一个 UserControl。
<Window x:Class="RoutedEventsTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:RoutedEventsTest"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Button Name="button" Click="ButtonBase_OnClick" HorizontalAlignment="Left"
VerticalAlignment="Top">Unhandled in parent</Button>
<local:ChildControl Grid.Row="1"/>
</Grid>
</Window>
using System.Windows;
namespace RoutedEventsTest
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
TestEventHandler += MainWindow_TestEventHandler;
}
void MainWindow_TestEventHandler(object sender, RoutedEventArgs e)
{
button.Content = "Handeled in parent";
e.Handled = false;
}
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
RaiseEvent(new RoutedEventArgs(TestEvent));
}
public static readonly RoutedEvent TestEvent = EventManager.RegisterRoutedEvent("TestEvent", RoutingStrategy.Tunnel, typeof(RoutedEventHandler), typeof(MainWindow));
public event RoutedEventHandler TestEventHandler
{
add { AddHandler(TestEvent, value); }
remove { RemoveHandler(TestEvent, value); }
}
}
}
<UserControl x:Class="RoutedEventsTest.ChildControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<TextBlock Name="textBlock">Unhandeled in child</TextBlock>
</Grid>
</UserControl>
using System.Windows;
using System.Windows.Controls;
namespace RoutedEventsTest
{
public partial class ChildControl : UserControl
{
public ChildControl()
{
InitializeComponent();
AddHandler(MainWindow.TestEvent, new RoutedEventHandler(TestEventHandler));
}
private void TestEventHandler(object sender, RoutedEventArgs routedEventArgs)
{
textBlock.Text = "Handled in child";
routedEventArgs.Handled = false;
}
}
}
当我运行该程序时,父窗口的 react 与我预期的一样,但子 UserControl 从未运行我传递给 AddHandler
的委托(delegate)。
将子控件更改为
public partial class ChildControl : UserControl
{
public ChildControl()
{
InitializeComponent();
AddHandler(TestEvent, new RoutedEventHandler(TestEventHandler));
}
public static readonly RoutedEvent TestEvent = EventManager.RegisterRoutedEvent("TestEvent", RoutingStrategy.Tunnel, typeof(RoutedEventHandler), typeof(ChildControl));
private void TestEventHandler(object sender, RoutedEventArgs routedEventArgs)
{
textBlock.Text = "Handled in child";
routedEventArgs.Handled = false;
}
}
也没有解决问题。我进行了大量搜索,发现了很多关于如何执行从子级到父级的冒泡事件的示例,但我找不到一个完整的示例来说明如何执行从父级到子级的隧道事件。
最佳答案
如果您查看 MSDN article on routed events in WPF ( archived ) 更仔细一点,您会看到上面写着:
Bubble
is the most common and means that an event will bubble (propagate) up the visual tree from the source element until either it has been handled or it reaches the root element. This allows you to handle an event on an object further up the element hierarchy from the source element.
Tunnel
events go in the other direction, starting at the root element and traversing down the element tree until they are handled or reach the source element for the event. This allows upstream elements to intercept the event and handle it before the event reaches the source element. Tunnel events have their names prefixed with Preview by convention (such as PreviewMouseDown).
这确实违反直觉,但隧道事件会向源元素传播。在您的例子中,root 元素是 MainWindow
,但 source 元素实际上是 ChildControl
。当您在 MainWindow
中引发事件时,它恰好是 source 和 root。
Source 元素是调用 RaiseEvent
方法的元素,即使 RoutedEvent
不是该元素的成员也是如此。 ,因为 RaiseEvent
是一个公共(public)方法,其他元素可以使另一个元素成为隧道事件的源元素。
换句话说,您需要类似的东西(添加了 Preview
前缀,因为这是隧道事件的约定):
// ChildControl is the event source
public partial class ChildControl : UserControl
{
public readonly static RoutedEvent PreviewEvent =
EventManager.RegisterRoutedEvent(
"PreviewEvent",
RoutingStrategy.Tunnel,
typeof(RoutedEventHandler),
typeof(ChildControl));
public ChildControl()
{
InitializeComponent();
AddHandler(PreviewEvent,
new RoutedEventHandler((s, e) => Console.WriteLine("Child handler")));
}
private void Button_Click(object sender, RoutedEventArgs e)
{
// make this control the source element for tunneling
this.RaiseEvent(new RoutedEventArgs(PreviewEvent));
}
}
在 MainWindow
中:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
AddHandler(ChildControl.PreviewEvent,
new RoutedEventHandler((s, e) => Console.WriteLine("Parent handler")));
}
}
如果您使用现有的隧道事件,事情会更简单,但请注意,它们仍然在 Button
上定义为源,而不是根元素:
// this uses the existing Button.PreviewMouseUpEvent tunneled event
public partial class ChildControl : UserControl
{
public ChildControl()
{
InitializeComponent();
AddHandler(Button.PreviewMouseUpEvent,
new RoutedEventHandler((s, e) => Console.WriteLine("Child handler")));
}
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
AddHandler(Button.PreviewMouseUpEvent,
new RoutedEventHandler((s, e) => Console.WriteLine("Parent handler")));
}
}
这还会将以下内容输出到控制台(鼠标松开时):
Parent handler
Child handler
当然,如果您在父处理程序中将 Handled
属性设置为 true
,则不会调用子处理程序。
[更新]
如果你想从父控件引发事件,但让子控件成为事件源,你可以简单地从外部调用子控件的公共(public) RaiseEvent
方法:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
AddHandler(ChildControl.PreviewEvent,
new RoutedEventHandler((s, e) => Console.WriteLine("Parent handler")));
}
private void Button_Click(object sender, RoutedEventArgs e)
{
// raise the child event from the main window
childCtrl.RaiseEvent(new RoutedEventArgs(ChildControl.PreviewEvent));
}
}
// child control handles its routed event, but doesn't know who triggered it
public partial class ChildControl : UserControl
{
public readonly static RoutedEvent PreviewEvent =
EventManager.RegisterRoutedEvent(
"PreviewEvent",
RoutingStrategy.Tunnel,
typeof(RoutedEventHandler),
typeof(ChildControl));
public ChildControl()
{
InitializeComponent();
AddHandler(PreviewEvent,
new RoutedEventHandler((s, e) => Console.WriteLine("Child handler")));
}
}
根据您的实际用例,您似乎希望父窗口在没有实际隧道的情况下通知子控件。在那种情况下,我不确定您是否需要事件? IE。这有什么问题:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
childCtrl.DoSomething(this, "MainWindow just sent you an event");
}
}
public partial class ChildControl : UserControl
{
public ChildControl()
{
InitializeComponent();
}
public void DoSomething(UIElement sender, string message)
{
Console.WriteLine(sender.ToString() + ": " + message);
}
}
关于c# - 进行隧道事件的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24876053/
是否有任何解决方案/补丁可以使 nginx 与上游的 socks 一起工作? 像这样: server { location / { proxy_pass socks5://ip:port
我的连接隧道有问题。因此,我正在使用两个安装了oracle xe(端口1521)的ubuntu服务器虚拟机,我们将它们称为uvm1和uvm2。我的目标是为两个服务器创建两个隧道,并将端口映射到主机,并
我正在使用 sshd 通过托管 Debian 的远程计算机隧道传输我所有的互联网流量。但是我的互联网连接变得很慢(大约 5 到 10 kbps!)。默认配置有什么问题会导致此问题吗? 提前致谢 最佳答
有没有办法在 OpenStreetMap 上显示所有隧道 + 道路?我正在为旅行制作自行车导航系统。在隧道中,我们丢失了 GPS 位置,因为隧道中没有 GPS 数据。我想知道我的位置进入隧道和离开隧道
我目前正在尝试在 Java 客户端(包括 Netty)和服务器之间实现一个 Http 隧道,所以我想知道是否有任何服务器也基于 Netty 来支持这个隧道,或者我应该构建服务器端我自己? 最佳答案 我
我希望从远程主机通过 SSH 建立一个端口。我希望将此实现为 oclif 插入;我希望用户体验如下所示: laptop$ give-jupyter http://localhost:4040/ lap
我正在寻找一种允许我使用 SSH 隧道连接到 R 中的 MySQL 服务器(而不是文件)的方法;我假设它需要 RCurl 和 RODBC 的组合,但我似乎无法让它正常工作。 我遇到了this post
基本上我想以编程方式通过代理服务器创建 SSL 隧道。我正在使用 openssl 创建 ssl 隧道,我可以创建它,但不确定如何通过代理服务器创建隧道。 最佳答案 快速谷歌搜索给我这个 pytunne
我想设置一个简单的 ssh 隧道,从本地机器到互联网上的机器。 我在用着 ssh -D 8080 -f -C -q -N -p 12122 @ 设置工作正常(我认为)导致 ssh 返回要求我提供的凭据
昨天,我接受了一家公司的 UI 开发面试。重点是面试官问了一个重要问题what is HTTP tunneling . 我从未遇到过有关 javascript、HTML 和 jquery 等 UI 内
对不起,长篇大论,我试图说得一清二楚。 * 一点背景 * 作为项目的一部分,我们需要能够使用远程桌面 (RDP) 从具有有效 IP 地址的服务器访问某些计算机(以下称为客户端)。这些客户端位于 NAT
我尝试了命令 killall ngrok,但我得到'killall' 未被识别为内部或外部命令、可操作程序或批处理文件。 killall 不应该和 ngrok 一起出现吗?我在互联网上找不到任何关于该
我需要连接到特定的 API,但该 API 只接受来 self 的配对服务器的请求。然后将这些信息包含在我们的网站中。 所以基本上我需要连接到服务器,使请求接收到答案并将其传输到我的主机,以便我可以使用
使用虚拟主机而不是部署的 Docker 容器,创建 ssh 隧道以便从我的本地机器访问分隔的机器对我来说是一个正常的工作过程。例如,将我的 psql 客户端连接到我只能从堡垒箱访问的 Postgres
我有一个从 Cloud Foundry 数据库转储数据的脚本,它的工作方式如下: cf ssh -L 33001:db.host:3306 --skip-remote-execution App &
我对以下系统架构有疑问: 假设我们有三台机器: SERVER A SERVER B EXTERNAL A SERVER A 正在提供一些流媒体服务,它在一个未知的网络后面,所以它在指定的端口上打开一个
我想从家庭计算机访问位于防火墙后面的工作计算机。 由于工作防火墙阻止意外的传入连接,我必须打开从工作计算机到家庭计算机的反向 SSH 隧道,如下所示: ssh -R 12345:localhost:2
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 这个问题似乎不是关于 a specific programming problem, a software
我遇到了 SSH 隧道问题,我知道这可能是我的本地端口的权限问题,很可能是 127.0.0.1:3308。但是,我已经以管理员身份运行了我的程序(sudo python3 myprogram.py),
我使用此链接在 centos linux 中创建 ip 隧道 http://www.techonia.com/create-tunnel-interface-linux . 然后我想删除现有的隧道,我
我是一名优秀的程序员,十分优秀!