模板部件不可用作可视子级。默认情况下是“自定义控件可见性”

问题描述 投票:0回答:1

我正在使用UserControl内部的sdl/Multiselect-ComboBox,默认情况下它已折叠。按下按钮后,UserControl可见性将设置为可见,因此应将所有内容加载到可视树中。如果可见性设置为“可见”,则按此顺序调用存储库控件。

1)静态MultiSelectComboBox()

2)公共重写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之前被调用,因此我创建了一个名为LoadComponent Function的函数,并且也从OnApplyTemplate中对其进行了调用。一切正常,除了以下内容始终为空,当我检查Visual Tree时,它甚至没有出现]

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>

我浪费我的时间试图思考可能的原因,但无法使它正常工作。

我在UserControl中使用的是sdl / Multiselect-ComboBox,默认情况下它已折叠。按下按钮后,UserControl Visibility设置为可见,因此应将所有内容加载到...

wpf xaml custom-controls dependency-properties
1个回答
0
投票

我没有检查代码,但是行为的属性也有类似的问题。

© www.soinside.com 2019 - 2024. All rights reserved.