Я использую sdl / Multiselect-ComboBox внутри моего UserControl, который по умолчанию свернут. При нажатии кнопки видимость UserControl становится видимой, и, следовательно, каждая вещь должна быть загружена в Visual Tree. Если видимость установлена на Видимый, элементы управления хранилищем вызываются в следующем порядке.
1) static MultiSelectComboBox ()
2) public override void OnApplyTemplate ()
3) ЗависимостьСвойства обратного вызова.
Когда события в этом порядке. Все работает как положено.
Но когда видимость установлена на Свернутый по умолчанию. Свойство зависимости вызывается перед OnApplyTemplate, что понятно. Проблема заключается в следующем обратном вызове. Загрузите все свойства и привяжите все необходимые события.
private static void ItemsPropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
{
LoadComponents(dependencyObject, dependencyPropertyChangedEventArgs);
}
private static void LoadComponents(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
{
var control = dependencyObject as MultiSelectComboBox;
if (control?.MultiSelectComboBoxGrid != null && control?.ItemsSource != null)
{
control.ItemsCollectionViewSource = new CollectionViewSource
{
Source = control.ItemsSource
};
if (dependencyPropertyChangedEventArgs.NewValue is IList newItems && newItems.Count > 0)
{
control.UpdateSelectedItemsContainer(newItems);
}
if (control.SelectedItemsControl == null)
{
control.SelectedItemsControl = VisualTreeService.FindVisualChild<ItemsControl>(control.MultiSelectComboBoxGrid, PART_MultiSelectComboBox_SelectedItemsPanel_ItemsControl);
}
if (control.DropdownListBox == null)
{
if (control.DropdownMenu == null)
{
control.DropdownMenu = VisualTreeService.FindVisualChild<Popup>(control.MultiSelectComboBoxGrid, PART_MultiSelectComboBox_Dropdown);
}
if (control.DropdownMenu != null)
{
control.DetachedFilterPanel = VisualTreeService.FindVisualChild<StackPanel>(control.DropdownMenu.Child, PART_MultiSelectComboBox_Detached_FilterPanel);
if (control.DetachedFilterPanel != null)
{
control.DetachedFilterTextBox = VisualTreeService.FindVisualChild<TextBox>(control.DetachedFilterPanel, PART_MultiSelectComboBox_Detached_Filter_TextBox);
control.DetachedFilterAutoCompleteTextBox = VisualTreeService.FindVisualChild<TextBox>(control.DetachedFilterPanel, PART_MultiSelectComboBox_Detached_Filter_AutoComplete_TextBox);
}
control.DropdownListBox = VisualTreeService.FindVisualChild<ListBox>(control.DropdownMenu.Child, PART_MultiSelectComboBox_Dropdown_ListBox);
}
}
}
}
Это в моем сценарии вызывается перед OnApplyTemplate, поэтому я создал функцию Called LoadComponent Function и также вызвал ее из OnApplyTemplate. Все работает нормально, за исключением того, что следующее всегда дает ноль, и когда я проверил дерево визуалов, его даже нет
if (control.SelectedItemsControl == null)
{
control.SelectedItemsControl = VisualTreeService.FindVisualChild<ItemsControl>(control.MultiSelectComboBoxGrid, PART_MultiSelectComboBox_SelectedItemsPanel_ItemsControl);
}
Я не могу понять причину этого. Вот Xaml для этой части
<DataTemplate x:Key="MultiSelectComboBox.SelectedItemsPanel.Template">
<Border Background="White" BorderBrush="{StaticResource MultiSelectComboBox.SelectedItemsPanel.Border}" BorderThickness="1">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="20"/>
</Grid.ColumnDefinitions>
<Border Grid.Column="0" Margin="1" Background="White" BorderThickness="0">
<sdl:ContentItemsControl x:Name="PART_MultiSelectComboBox_SelectedItemsPanel_ItemsControl"
ItemContainerStyle="{StaticResource MultiSelectComboBox.SelectedItems.ItemContainer.Style}"
Style="{StaticResource MultiSelectComboBox.SelectedItemsPanel.WrapableItemsSource.Style}">
<sdl:ContentItemsControl.Resources>
<DataTemplate x:Key="MultiSelectComboBox.SelectedItems.ItemTemplate">
<TextBlock Text="{Binding}" Style="{DynamicResource MultiSelectComboBox.DefaultTextBlock.Style}" Margin="2,0" />
</DataTemplate>
<DataTemplate x:Key="MultiSelectComboBox.SelectedItems.Searchable.ItemTemplate">
<StackPanel Orientation="Horizontal">
<TextBox x:Name="PART_MultiSelectComboBox_SelectedItemsPanel_Filter_TextBox" IsEnabled="{Binding IsEditMode, RelativeSource={RelativeSource TemplatedParent}}"
Focusable="True" IsTabStop="False" Margin="0" ForceCursor="True" BorderThickness="0" BorderBrush="Transparent" Padding="1" TextWrapping="NoWrap"/>
<TextBox x:Name="PART_MultiSelectComboBox_SelectedItemsPanel_Filter_AutoComplete_TextBox" IsReadOnly="True"
Focusable="False" IsTabStop="False" Margin="-2,0,0,0" BorderThickness="0" BorderBrush="Transparent" Padding="-3,1,0,1" TextWrapping="NoWrap"/>
</StackPanel>
</DataTemplate>
</sdl:ContentItemsControl.Resources>
</sdl:ContentItemsControl>
</Border>
<Button x:Name="PART_MultiSelectComboBox_Dropdown_Button" Grid.Column="1" Style="{StaticResource MultiSelectComboBox.DropDown.Button.Style}" >
<ContentControl>
<ContentControl.Style>
<Style TargetType="ContentControl">
<Setter Property="IsTabStop" Value="False"/>
<Setter Property="ContentTemplate" Value="{StaticResource MultiSelectComboBox.SelectedItemsPanel.Readonly.Glyph.Template}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type sdl:MultiSelectComboBox}}, Path=IsEditMode}" Value="True">
<Setter Property="ContentTemplate" Value="{StaticResource MultiSelectComboBox.SelectedItemsPanel.EditMode.Glyph.Template}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
</Button>
</Grid>
</Border>
</DataTemplate>
<Style x:Key="MultiSelectComboBox.Custom.Style" TargetType="{x:Type sdl:MultiSelectComboBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type sdl:MultiSelectComboBox}">
<Grid x:Name="PART_MultiSelectComboBox" MaxHeight="{TemplateBinding ActualHeight}" MaxWidth="{TemplateBinding ActualWidth}" Style="{StaticResource MultiSelectComboBox.Style}">
<ToggleButton KeyboardNavigation.TabNavigation="None" IsChecked="{Binding Path=IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" IsTabStop="False">
<ToggleButton.Template>
<ControlTemplate TargetType="ToggleButton">
<ContentControl ContentTemplate="{StaticResource MultiSelectComboBox.SelectedItemsPanel.Template}"/>
</ControlTemplate>
</ToggleButton.Template>
</ToggleButton>
<Popup x:Name="PART_MultiSelectComboBox_Dropdown" Margin="2" Grid.ColumnSpan="2" MaxHeight="{Binding Path=MaxDropDownHeight, RelativeSource={RelativeSource TemplatedParent} }" PlacementTarget="{Binding ElementName=PART_MultiSelectComboBox}" IsOpen="{Binding Path=IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" MaxWidth="{TemplateBinding ActualWidth}" Placement="Bottom" AllowsTransparency="True" PopupAnimation="Slide">
<themes:SystemDropShadowChrome x:Name="shadow" Color="Transparent" MinWidth="{Binding ActualWidth, ElementName=PART_MultiSelectComboBox}">
<Border x:Name="dropDownBorder" Margin="0,1,0,0" BorderBrush="{DynamicResource {x:Static SystemColors.WindowFrameBrushKey}}" BorderThickness="0" Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0" Visibility="{Binding DetachAutoCompleteFilterBox, RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource BoolToVis},FallbackValue=Collpased}">
<Border BorderBrush="LightBlue" BorderThickness="1">
<Border.Effect>
<DropShadowEffect ShadowDepth="0" Color="LightBlue" Opacity="1" BlurRadius="10"/>
</Border.Effect>
</Border>
<Border Padding="2">
<StackPanel x:Name="PART_MultiSelectComboBox_Detached_FilterPanel" Orientation="Horizontal" Height="30">
<TextBox x:Name="PART_MultiSelectComboBox_Detached_Filter_TextBox" Margin="1,0,0,0" IsEnabled="{Binding IsEditMode, RelativeSource={RelativeSource TemplatedParent}}"
Focusable="True" IsTabStop="False" ForceCursor="True" BorderThickness="0" BorderBrush="Transparent" Padding="1" TextWrapping="NoWrap"/>
<TextBox x:Name="PART_MultiSelectComboBox_Detached_Filter_AutoComplete_TextBox" IsReadOnly="True"
Focusable="False" IsTabStop="False" Margin="-2,0,0,0" BorderThickness="0" BorderBrush="Transparent" Padding="-3,1,0,1" TextWrapping="NoWrap"/>
</StackPanel>
</Border>
</Grid>
<Grid x:Name="grid" Grid.Row="1" RenderOptions.ClearTypeHint="Enabled"
Visibility="{Binding Path=IsLoadingSuggestions,
RelativeSource={RelativeSource Mode=TemplatedParent},
Converter={StaticResource ResourceKey=InvBoolToVis}}"
>
<Grid Visibility="{Binding Path=IsLoadingSuggestions,
RelativeSource={RelativeSource Mode=TemplatedParent},
Converter={StaticResource ResourceKey=InvBoolToVis}}">
<Canvas x:Name="canvas" HorizontalAlignment="Left" Height="0" VerticalAlignment="Top" Width="0">
<Rectangle x:Name="opaqueRect" Fill="{Binding Background, ElementName=dropDownBorder}" Height="{Binding ActualHeight, ElementName=dropDownBorder}" Width="{Binding ActualWidth, ElementName=dropDownBorder}"/>
</Canvas>
<sdl:ExtendedListBox x:Name="PART_MultiSelectComboBox_Dropdown_ListBox" Style="{StaticResource MultiSelectComboBox.Dropdown.ListBox.Style}">
<sdl:ExtendedListBox.GroupStyle>
<GroupStyle HeaderTemplate="{StaticResource MultiSelectComboBox.Dropdown.ListBox.Header.Template}"/>
</sdl:ExtendedListBox.GroupStyle>
<sdl:ExtendedListBox.Resources>
<DataTemplate x:Key="MultiSelectComboBox.Dropdown.ListBox.ItemTemplate">
<TextBlock Text="{Binding}" Style="{StaticResource MultiSelectComboBox.DefaultTextBlock.Style}" Margin="2,2,2,3"/>
</DataTemplate>
</sdl:ExtendedListBox.Resources>
</sdl:ExtendedListBox>
</Grid>
<ContentPresenter ContentSource="LoadingSuggestionsContent"
Visibility="{Binding Path=IsLoadingSuggestions,
RelativeSource={RelativeSource Mode=TemplatedParent},
Converter={StaticResource ResourceKey=BoolToVis}}"/>
</Grid>
</Grid>
</Border>
</themes:SystemDropShadowChrome>
</Popup>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Я потратил впустую свой день, пытаясь придумать возможную причину, но не смог заставить это работать.