C# wpf中的路由隧道事件

C# wpf中的路由隧道事件,c#,wpf,events,user-controls,routed-events,C#,Wpf,Events,User Controls,Routed Events,我有一个问题要问wpf社区。 我有点无法理解隧道事件的路由。在我的应用程序中,我有一个包含工具栏的窗口。 窗口还包含用户控件。在工具栏中有一些控件,如视图,用于隐藏/取消隐藏用户控件(视图),如在VisualStudio中 我在windows控件中有自定义路由隧道事件。单击工具栏上的按钮(隐藏/取消隐藏)时引发自定义事件。单击按钮时,我需要在子用户控件(其名称类似于“expander 1”)中隐藏一个扩展器 有人能告诉我如何在子用户控件中捕获引发的事件吗 谢谢 代码窗口: public part

我有一个问题要问wpf社区。 我有点无法理解隧道事件的路由。在我的应用程序中,我有一个包含工具栏的窗口。 窗口还包含用户控件。在工具栏中有一些控件,如视图,用于隐藏/取消隐藏用户控件(视图),如在VisualStudio中

我在windows控件中有自定义路由隧道事件。单击工具栏上的按钮(隐藏/取消隐藏)时引发自定义事件。单击按钮时,我需要在子用户控件(其名称类似于“expander 1”)中隐藏一个扩展器

有人能告诉我如何在子用户控件中捕获引发的事件吗

谢谢

代码窗口:

public partial class MainWindow : Window
    {
        private static readonly RoutedEvent HideShowMitigationEvent;

        static MainWindow()
            {
            HideShowMitigationEvent = EventManager.RegisterRoutedEvent("HideShowMitigation",
                RoutingStrategy.Tunnel, typeof(RoutedEventHandler), typeof(MainWindow));
            }

        public MainWindow()
            {
            InitializeComponent();
            }

        // The Standard .Net optional event wrapper
        // This is required if we want to register the event handler in XAML       
        public event RoutedEventHandler HideShowMitigation
            {
            add { AddHandler(HideShowMitigationEvent, value); }
            remove { RemoveHandler(HideShowMitigationEvent, value); }
            }

        // Raise the event. overidden from UIElement       
        protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
            {
           // RaiseEvent(new RoutedEventArgs(HideShowMitigationEvent, this));
            }


        public static ExploredRisks _rootName { get; set; }

        public MainWindow(GeneralTree<string> rawTreeData, Excel.Worksheet sheet,Excel.Workbook Wb)
        {

            //prepares the visual tree for other views
            PrepareVisualTree visualTree = new PrepareVisualTree(rawTreeData, sheet);
            _rootName = visualTree.getVisualTree();
            var l_vm = new MainViewModel();
            l_vm.Load(_rootName);
           TreeListViewMultiColumned view = new TreeListViewMultiColumned( RiskViewModel.CreateTestModel(visualTree.getVisualTree()),sheet,Wb);


            base.DataContext = l_vm;
            InitializeComponent();

        }

        private void UIPanel_Loaded(object sender, RoutedEventArgs e)
        {

        }


        private void RibbonCheckBox_Checked(object sender, RoutedEventArgs e)
        {

           RaiseEvent(new RoutedEventArgs(HideShowMitigationEvent, this));
        }

        private void SimpleClickEventHandlingCode(object sender, RoutedEventArgs e)
            {
            //Expander exp = ((MainWindow)(e.OriginalSource)).RiskProperties.MitigationArea; 
                RoutedEventArgs args = new RoutedEventArgs();
                args.RoutedEvent = HideShowMitigationEvent;
                 RaiseEvent(args);
            }
    }
}
公共部分类主窗口:窗口
{
私有静态只读RoutedEvent HideShowRelationEvent;
静态主窗口()
{
HideshowMigrationEvent=EventManager.RegisterRoutedEvent(“HideshowMigrationEvent”,
路由策略隧道,类型(路由隧道),类型(主窗口);
}
公共主窗口()
{
初始化组件();
}
//标准的.Net可选事件包装器
//如果我们想在XAML中注册事件处理程序,这是必需的
公共活动路线——温坦德尔·希德肖夫缓解
{
添加{AddHandler(HideshowMigrationEvent,value);}
删除{RemoveHandler(HideshowMigrationEvent,value);}
}
//从UIElement引发事件
MouseLeftButtonDown上的受保护覆盖无效(MouseButtonEventArgs e)
{
//RaiseEvent(新路由EventArgs(HideShow缓解事件,本));
}
公共静态ExploredRisks_rootName{get;set;}
公共主窗口(GeneralTree rawTreeData、Excel.工作表、Excel.Workbook Wb)
{
//为其他视图准备可视化树
PrepareVisualTree visualTree=新的PrepareVisualTree(原始数据,表格);
_rootName=visualTree.getVisualTree();
var l_vm=新的MainViewModel();
l_vm.Load(_rootName);
TreeListViewMultiColumned视图=新的TreeListViewMultiColumned(RiskViewModel.CreateTestModel(visualTree.getVisualTree()),工作表,Wb);
base.DataContext=l_vm;
初始化组件();
}
已加载专用无效UIPanel_(对象发送器,路由目标e)
{
}
已选中private void RibbonCheckBox_(对象发送方,路由目标e)
{
RaiseEvent(新路由EventArgs(HideShow缓解事件,本));
}
private void SimpleClickEventHandlingCode(对象发送方,RoutedEventTarget e)
{
//Expander exp=((主窗口)(如OriginalSource)).RiskProperties.relationarea;
RoutedEventTargets args=新RoutedEventTargets();
args.RouteEvent=隐藏缓解事件;
RaiseEvent(args);
}
}
}
窗口Xaml:

<Window>


       <Ribbon x:Name="RibbonWin"  SelectedIndex="0">
             <RibbonTab Header="Views" KeyTip="H">
                <!-- Home  group-->
                <RibbonGroup x:Name="ViewsGroup" Header="Views">
                    <RibbonCheckBox Label="Mitigation" IsChecked="{Binding IsChecked, Mode=TwoWay}" Checked="RibbonCheckBox_Checked" PreviewMouseDown="SimpleClickEventHandlingCode"/>
                    <RibbonCheckBox Label="Properties" IsChecked="{Binding IsChecked, Mode=TwoWay}" Checked="RibbonCheckBox_Checked" />
                </RibbonGroup>
            </RibbonTab>
        </Ribbon>
  <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
            <UI:TreeListViewMultiColumned x:Name="RiskProperties"  Grid.Column="0"  />
        </Grid>
</Window>

我想在提出解决方案之前,我必须澄清WPF路由事件:

在WPF中,有一个路由事件的新概念。路由事件是沿逻辑树传递的事件

例如: 让我们看看当你点击UI上的一个按钮时会发生什么。 首先,您将获得一个PreviewLeftMouseButtonDown事件,该事件发生在主窗口上,然后从父元素树向下传递到子元素树,直到它到达已单击的按钮。 ->这个过程(从父代到子代)称为隧道

其次,您将得到一个LeftMouseButtonDown事件,该事件发生在按钮上,并向上传递元素树,直到它到达主窗口。 ->这个过程(从子代到父代)称为“冒泡”

据我所知,您想点击按钮打开扩展器。 IMHO为此使用路由事件不是合适的方法

我认为您可以用一点XAML来解决您的用例。以下是我的建议:

  • 使用工具栏中的切换按钮(这确保用户可以 查看按钮的状态,例如按下或未按下。)
  • 使用数据绑定将ToggleButtons IsChecked属性绑定到 扩展器是扩展属性
检查以下(高度简化)示例:


这是我的头球
这是我的身体

备注:我的想法是,只有当UserControl在您的控制下时,这才有效。如果是这样的话:很好,否则我将描述另一种解决方案。
Rgds MM

谢谢,但它与您解释的方式不一样。我试过了。虽然isChecked设置为true,但绑定不会相应地将扩展器可见性设置为true或false。代码中一定有问题。如果你发布你当前的代码,我会看一看。
<Grid>
  <StackPanel>
     <ToggleButton x:Name="openExpanderBtn" Width="100" Height="30" Margin="20" Content="Click to Open" />
     <Expander Width="150" Height="200" IsExpanded="{Binding ElementName=openExpanderBtn, Path=IsChecked}" >
        <Expander.Header>
           This is my Header
        </Expander.Header>
        This is my Body
     </Expander>
  </StackPanel>