我在这里向wpf社区提出了一个问题。 我有点无法理解路由隧道事件。在我的应用程序中,我有一个包含工具栏的窗口。 窗口还包含用户控件。工具栏中有一些控件,如视图,用于隐藏/取消隐藏用户控件(视图),就像在Visual Studio中一样。
我在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);
}
}
}
Window 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>
答案 0 :(得分:0)
我认为在建议解决方案之前,我必须澄清WPF路由事件:
在WPF中,有一个新的路由事件概念。路由事件是沿逻辑树传递的事件。
实施例: 让我们看一下当您单击UI上的按钮时会发生什么。 首先,您将获得MainWindow上发生的PreviewLeftMouseButtonDown事件,然后将元素树从父级传递到子级,直到它到达已单击的按钮。 - &GT;此过程(从父级到子级)称为隧道
其次,您将获得一个在按钮上发生的LeftMouseButtonDown事件,并在元素树中向上传递,直到它到达MainWindow。 - &GT;这个过程(从孩子到父母)被称为冒泡
据我了解,您想要点击按钮打开扩展器。 恕我直言,使用路由事件是不合适的方法。
我认为你可以用一点XAML来解决你的用例。以下是我的建议:
检查以下(高度简化的)样本:
<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