WPF: Как создавать события для пользовательских элементов управления? - PullRequest
4 голосов
/ 29 марта 2011

Я создал UserControl, который состоит из ItemsCollection.Каждый предмет в этой коллекции состоит из ListBox.

Мое приложение представлено 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>

Ответы [ 3 ]

2 голосов
/ 29 марта 2011

@ Влад находится на правильном пути.

Здесь есть несколько вариантов. Оба они связаны с обработкой перенаправленных событий.

Для обработки перенаправленного события вы используете имя класса-владельца, за которым следует имя события.

Первый вариант - просто обработать выбранные измененные события (или некоторые другие ListBox события) в классе Window:

<Window ...
        ListBox.SelectionChanged="OnChildListboxSelectionChanged">
   ...
</Window>

Второй вариант (более типичный подход) - обрабатывать события ListBox внутри UserControl, а затем каким-то образом их агрегировать и запускать событие на этом уровне. Это событие затем обрабатывается 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>

Это должно дать вам кое-что для начала.

1 голос
/ 29 марта 2011

Я сам их мало использовал, но думаю, RoutedEvents решит вашу проблему.События всплывают от вашего ListBox до Window (или другого элемента ниже в дереве), где вы можете с ними справиться.

edit : цитирование по ссылке: Добавитьобработчик события, использующий XAML, вы объявляете имя события как атрибут элемента, который является прослушивателем событий.Значением атрибута является имя вашего реализованного метода-обработчика, который должен существовать в частичном классе файла с выделенным кодом.

, поскольку UserControl наследуется от UIElement,Я предполагаю, что что-то вроде этого будет работать (не проверено банкомат):

<UserControl
    x:Class="UserControls.CalendarMonthViewControl.CalendarMonthView"
    [...]
    ListBox.NameOfEvent="EventHandlerName">
0 голосов
/ 29 марта 2011

Я не думаю, что вы пытаетесь сделать правильный подход, поскольку он создает ненужную зависимость между вашими представлениями и означает, что ваш UserControl не инкапсулирован должным образом.

На мой взгляд, хорошим решением было быбыть для обработки событий в viewmodel вашего UserControl и при необходимости установить отношение между viewmodel вашего Window, чтобы сами представления были независимыми.

...