用户控件与父控件交互的实现

在WPF应用程序开发中,经常需要在用户控件(UserControl)与父控件之间进行交互。例如,当用户在用户控件中点击一个按钮或展开一个扩展器(Expander)时,可能需要在父控件中做出响应。本文将介绍一种实现这种交互的方法,通过一个具体的示例,展示如何使用Expander控件在用户控件中触发事件,并由父控件处理。

目标是实现一个父控件,它包含一个ScrollViewer,里面放置了一个StackPanel。在StackPanel中,有一个ItemsControl,它的ItemTemplate是一个用户控件类型,绑定到ItemsControl.ItemsSource。当用户展开其中一个子Expander时,该用户控件会触发一个事件,父控件会捕获这个事件并处理子集合。问题在于StackPanel的子集合是一个ItemsControl,需要从中获取Expanders。

用户控件- myTema

用户控件myTema基本上是一个Expander,其中包含一些消耗绑定数据的元素(在例子中,是一个HeaderTemplate和一些不需要的嵌套用户控件),以及一个绑定到Expanded事件的动作:

<Grid x:Name="LayoutRoot"> <toolkit:Expander x:Name="ExpanderTema" Expanded="ExpanderTema_Expanded" HeaderTemplate="{StaticResource ExpanderTemaDataTemplate}" Header="{Binding myTema_Conteudo, ElementName=myTemaRoot}"> <StackPanel x:Name="stackSugest"> </StackPanel> </toolkit:Expander> </Grid>

在C#中,定义了一个事件ExpanderTemaExpanded,并在ExpanderTema_Expanded方法中触发该事件:

public event EventHandler ExpanderTemaExpanded; private void ExpanderTema_Expanded(object sender, System.Windows.RoutedEventArgs e) { ExpanderTemaExpanded?.Invoke(sender, null); }

父控件

父控件的ItemsControl.ItemsSource基于一个本地变量,并捕获其任何用户控件子项的ExpanderTemaExpanded事件。

List<myTema_Info> ListTema = new List<myTema_Info>(); itemsMyTemas.ItemsSource = ListTema; <ScrollViewer x:Name="ScrollViewer1"> <Grid> <StackPanel x:Name="stackMyTemas"> <ItemsControl x:Name="itemsMyTemas"> <ItemsControl.ItemTemplate> <DataTemplate> <componente:myTema x:Name="myCategory_Temas" ExpanderTemaExpanded="myCategory_Temas_ExpanderTemaExpanded" myTema_Conteudo="{Binding}" /> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> </StackPanel> </Grid> </ScrollViewer>

在由用户控件调用的方法中,ExpanderTemaExpanded事件是处理的核心,其中使用了GetAllChildFrameworkElement函数,该函数在下一节中解释。

private void myCategory_Temas_ExpanderTemaExpanded(object sender, System.EventArgs e) { var found = Tools.GetAllChildFrameworkElement(stackMyTemas, typeof(Expander)); foreach (Expander item in found) { if (item != (Expander)sender) { item.IsExpanded = false; } } }

在案例中,使用了一个通用静态类,其中包含了所有通用函数,如在父StackPanel子集合中查找所有Expander所需的函数。

public static class Tools { public static List<FrameworkElement> GetAllChildFrameworkElement(FrameworkElement parentElement, Type typeRequired) { List<FrameworkElement> childFrameworkElementFound = new List<FrameworkElement>(); SearchAllChildFrameworkElement(parentElement, childFrameworkElementFound, typeRequired); return childFrameworkElementFound; } private static void SearchAllChildFrameworkElement(FrameworkElement parentFrameworkElement, List<FrameworkElement> allChildFrameworkElement, Type typeRequired) { int childrenCount = VisualTreeHelper.GetChildrenCount(parentFrameworkElement); if (childrenCount > 0) { for (int i = 0; i < childrenCount; i++) { FrameworkElement childFrameworkElement = (FrameworkElement)VisualTreeHelper.GetChild(parentFrameworkElement, i); if (childFrameworkElement.GetType().Equals(typeRequired)) { allChildFrameworkElement.Add(childFrameworkElement); } SearchAllChildFrameworkElement(childFrameworkElement, allChildFrameworkElement, typeRequired); } } } }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485