wpf中的路由隧道事件

本文关键字:隧道 事件 路由 wpf | 更新日期: 2023-09-27 18:01:58

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

我有自定义路由隧道事件在窗口控制。当单击工具栏上的按钮(隐藏/取消隐藏)时,我会引发自定义事件。当按钮被点击时,我需要隐藏一个扩展器在子用户控制(它有一个像"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);
            }
    }
}

窗口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路由事件:

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

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

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

据我所知,你想在点击按钮时打开扩展器。恕我直言,使用路由事件不是合适的方法。

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

  • 您在工具栏中使用ToggleButton(这确保用户可以查看按钮的状态,例如按下或未按下)
  • 你使用数据绑定将ToggleButtons的IsChecked属性绑定到

检查以下(高度简化)示例:

<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>

备注:它只是来到我的脑海中,这只工作,如果UserControl是在你的控制之下。如果是这种情况,那很好,否则我将描述另一种解决方案。Rgds MM