WPF:如何为自定义用户控件创建事件?
我创建了UserControl
,它由组成。此集合中的每件商品均由ListBox
组成。WPF:如何为自定义用户控件创建事件?
我的申请表示为Window
,其中包含UserControl
。我希望能够管理与ListBox
中的物品相关的活动。我怎样才能做到这一点? (我不知道这是否是相关与否,但UserControl
是一个从应用程序组件不同。)
这里是UserControl
的代码:
<UserControl
x:Class="UserControls.CalendarMonthViewControl.CalendarMonthView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignWidth="580"
d:DesignHeight="300"
xmlns:calendarMonthViewControl="clr-namespace:UserControls.CalendarMonthViewControl"
Name="CalendarMonthViewControl">
<Grid>
<ItemsControl
ItemsSource="{Binding ElementName=CalendarMonthViewControl, Path=Days}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="6" Columns="7" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type calendarMonthViewControl:Day}">
<Border>
<Grid>
<ListBox ItemsSource="{Binding Path=CalendarDayItems}" />
</Grid>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</UserControl>
@vlad走上正轨。
这里有几个选项。他们都涉及处理路由事件。
要处理路由事件,请使用拥有类的名称,后跟事件的名称。
第一种选择是简单地处理该选择的Window
类改变事件(或一些其它ListBox
事件):
<Window ...
ListBox.SelectionChanged="OnChildListboxSelectionChanged">
...
</Window>
第二个选项(更典型的方法)是处理内的ListBox
事件用户控件,然后以某种方式聚合它们并在该级别激发事件。此事件由Window
处理。此事件可能是路由事件或标准.NET事件。
<UserControl ...
ListBox.SelectionChanged="OnChildListBoxSelectionChanged">
...
</UserControl>
后面的代码在用户控制:
public event EventHandler<MyArgTypeEventArgs> ListBoxUpdated;
private void OnChildListBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
{
// aggregate data and info
MyArgTypeEventArgs handler = ListBoxUpdated;
if (handler != null)
handler.Invoke(this, GenerateArgs());
}
的Window
处理此事件:
<Window ...
ListBoxUpdated="OnListBoxUpdated">
...
</Window>
这应该给你的东西开始。
请注意,如果你愿意,你可以使用类似的方法使用MVVM。视图必须在事件发生时通知视图模型,然后视图模型将聚合并传播事件。 – 2011-03-29 13:56:55
MVVM在使用ItemsControls或ListBoxes中的DataTemplates时效果最佳。如果没有在控件中使用视图模型,可能很难在ItemsControl中使用与单个项目相关联的逻辑。 – 2011-03-29 13:59:07
非常感谢。我决定给MVVM一个镜头(我之前从未使用过我的编码)。 – Boris 2011-03-29 20:50:46
我没有使用过他们多少我自己,但我认为RoutedEvents会解决你的问题。事件从您的ListBox
冒泡到Window
(或树中较低的另一元素),您可以在其中处理它们。
编辑:从引用链接:要使用XAML事件添加处理程序,需要声明的事件名称,因为这是一个事件侦听器的元素的属性。该属性的值是您实现的处理程序方法的名称,该名称必须存在于代码隐藏文件的部分类中。从UIElement
因为UserControl
继承,我猜是这样会工作(未经测试ATM):
<UserControl
x:Class="UserControls.CalendarMonthViewControl.CalendarMonthView"
[...]
ListBox.NameOfEvent="EventHandlerName">
我不认为你想做什么是正确的做法,因为它的创建您的视图之间不必要的依赖,意味着您的UserControl没有正确封装。
在我看来,最好的解决方案是处理UserControl的viewmodel中的事件,并根据需要在您的Window的viewmodel之间建立关系,以便视图本身是独立的。
感谢您的回复。好的,比方说,我在'UserControl'中调用一个事件。用户控件的代码隐藏将包含事件处理程序。我如何从包含'UserControl'的'Window'代码隐藏内部到达该方法?或者,如果我再次想到错误,请你帮我理解应该怎么做?谢谢一堆。 – Boris 2011-03-29 13:53:04
可以用中介完成。这一切都取决于你的作品如何耦合。如果您使用的是MVVM,它将取决于您的视图模型如何耦合。 – 2011-03-29 13:55:11
@Boris,因为Josh说你需要粘贴这些视图的东西,通过它没有使用MVVM的声音,我会给它一个阅读并削减代码背后的代码,它会在以后偿还一个更清洁的架构,视图和您的业务逻辑很好地分离! – dain 2011-03-29 14:06:24
你想在哪里处理ListBox事件?在窗口中,用户控件还是其他地方?有人必须“处理”事件。 – 2011-03-29 13:39:24
我想在'Window'的代码后面处理事件。 – Boris 2011-03-29 13:41:59