Я создал элемент управления listbox и переопределил стиль ListBoxItem следующим образом:
<Style TargetType="{x:Type customControls:CheckedListBox}"
BasedOn="{StaticResource {x:Type ListBox}}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Expander x:Name="PART_Expander" IsExpanded="True">
<ItemsPresenter/>
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="SelectionMode" Value="Multiple"/>
<Style.Resources>
<Style TargetType="ListBoxItem" x:Name="PART_ListBoxItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<CheckBox Selector.IsSelected="True" IsChecked="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}, Path=IsSelected}" Content="{Binding Path=.}">
</CheckBox>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="IsSelected" Value="True"/>
</Style>
</Style.Resources>
</Style>
В коде позади CheckedListBox я вызываю событие, когда нажимаются какие-либо флажки:
protected override void OnSelectionChanged(SelectionChangedEventArgs e)
{
base.OnSelectionChanged(e);
RaiseRefreshDataEvent(e.RemovedItems);
}
protected virtual void RaiseRefreshDataEvent(IList changedItems)
{
RefreshDataSetEventArgs args = new RefreshDataSetEventArgs(CheckedListBox.RefreshDataSetEvent, changedItems);
RaiseEvent(args);
}
public static readonly RoutedEvent RefreshDataSetEvent =
EventManager.RegisterRoutedEvent("RefreshDataSet", RoutingStrategy.Bubble,
typeof(RefreshDataSetEventHandler), typeof(CheckedListBox));
public event RefreshDataSetEventHandler RefreshDataSet
{
add { AddHandler(RefreshDataSetEvent, value); }
remove { RemoveHandler(RefreshDataSetEvent, value); }
}
public delegate void RefreshDataSetEventHandler(Object sender, RefreshDataSetEventArgs e);
public class RefreshDataSetEventArgs : RoutedEventArgs
{
public IList ValueChanged { get; set; }
public RefreshDataSetEventArgs(RoutedEvent routedEvent, IList valuesChanged) : base(routedEvent)
{
ValueChanged = valuesChanged;
}
}
Теперь я хочу перехватить RefreshDataSetEvent в одном из родительских элементов CheckedListBox.Я смог сделать это, просматривая объекты визуального дерева, находя CheckedListBox и добавляя метод из родительского класса к объекту, используя RefreshDataSet.Это кажется как хак для меня.Я ожидал бы, что если событие действительно пузырится в визуальном дереве, я должен быть в состоянии перехватить его без необходимости явного добавления обработчика к исходному объекту.Любая идея, как я могу поймать это событие без явной установки обработчика объекта?
EDIT
CheckBoxList используется в другом настраиваемом элементе управления с именем FilterDataGrid (это класс, который я хотел быобрабатывать событие).Вот стиль для FilterDataGrid:
<Style TargetType="{x:Type customControls:FilterDataGrid}"
BasedOn="{StaticResource {x:Type DataGrid}}">
<Style.Resources>
<Style TargetType="{x:Type DataGridColumnHeader}" x:Name="PART_DataGridColumnHeader">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<StackPanel>
<customControls:CheckedListBox ItemsSource="{Binding Path=.}"/>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Height" Value="Auto"/>
<Setter Property="Background" Value="Black"/>
</Style>
</Style.Resources>
</Style>
Итак, когда я пытаюсь добавить customControls: CheckedListBox.RefreshDataSet = "TestThis" к стилю, я получаю сообщение об ошибке, указывающее на использование EventSetter.Когда я добавляю следующее к стилю для установщика событий, я получаю «Неизвестная ошибка сборки, ссылка на объект не установлена на экземпляр объекта»: Согласно документам, вы не можете использовать набор событий в файле Generic.xaml,Или, по крайней мере, это то, что я извлек из:
Установщики событий не могут использоваться в стиле, который содержится в словаре ресурсов темы.Это связано с тем, что словарь ресурсов темы во время выполнения часто представляет собой потерянные двоичные файлы XAML (BAML) и не имеет какой-либо определенной области, где может существовать сопровождающий код, определяющий обработчики.
Так что ямне интересно, как мне настроить Eventhandler, если я не могу указать его в файле Themes / Generic.xaml.