Search code examples
.netwpfcustom-controlsdatatemplatedependency-properties

WPF CustomControl pass through of datatemplate to listbox not working


I am learning about custom controls and am making an autoCompleteTextBox as an example. I am creating the custom control for a WPF project (v 4.5 with vb.net 4.5) and it is using a textbox base class. I then added a popup, listbox, and button to the control. I have a dependency property in the custom control for datatemplate of the listbox, but I can't get the datatemplate pssed to the listbox.

here is the dependency property for the datatemple:

#Region "DEPENDENCY PROPERTIES -- ItemTemplate"
    Public Property ItemTemplate As DataTemplate
        Get
            Return GetValue(ItemTemplateProperty)
        End Get
        Set(ByVal value As DataTemplate)
            SetValue(ItemTemplateProperty, value)
        End Set
    End Property
    Public Shared ReadOnly ItemTemplateProperty As DependencyProperty = DependencyProperty.Register( _
                        "ItemTemplate", GetType(DataTemplate), GetType(AutoCompleteTextBox), _
                        New FrameworkPropertyMetadata(Nothing, FrameworkPropertyMetadataOptions.None, _
                        New PropertyChangedCallback(AddressOf OnItemTemplateChanged)))

    Shared Sub OnItemTemplateChanged(d As DependencyObject, e As DependencyPropertyChangedEventArgs)
        Dim actb As AutoCompleteTextBox = TryCast(d, AutoCompleteTextBox)
         If actb IsNot Nothing Then
            Dim TempTemplate As DataTemplate = TryCast(e.NewValue, DataTemplate)
            If TempTemplate IsNot Nothing Then
                actb.ItemTemplate = TempTemplate
            End If
        End If
     End Sub
#End Region

Here is my xaml for declaring a small text of the usercontrol:

<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:krisis="clr-namespace:Krisis.Controls;assembly=Krisis.Controls"
    Title="MainWindow" Height="350" Width="525" x:Name="MyWindow"
    DataContext="{Binding RelativeSource={RelativeSource Self}}">
    <Window.Resources>
        <DataTemplate x:Key="CollectionTemplate">
            <Border BorderBrush="Green" BorderThickness="2" CornerRadius="5" Padding="5,5,5,2">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition/>
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition/>
                        <RowDefinition/>
                    </Grid.RowDefinitions>
                    <TextBlock Text="OBJECT:  "/>
                    <TextBlock Grid.Column="1" Text="{Binding Name}"/>
                    <TextBlock Grid.Row="1" Text="{Binding id}"/>
                    <TextBlock Grid.Column="1" Grid.Row="1" Text="{Binding Job}"/>
                </Grid>
            </Border>
        </DataTemplate>
    </Window.Resources>
    <Grid>
        <krisis:AutoCompleteTextBox ItemsSource="{Binding Collection}" 
                                    ItemTemplate="{StaticResource CollectionTemplate}" 
                                    MaxmimumMatches="15" 
                                    MinimumFilterCharacters="1" 
                                    DisplayPath="Name"
                                    Width="497" MinHeight="35" FontSize="18" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="10,41,10,243" />
    </Grid>
</Window>

MY PROBLEM: is that when I use this to declare my itemtemplate, it is not getting applied. The listbox just displays the object type name for each object in the listbox, not any of the object property values.

Can someone help me use a dependency property to pass through the DataTemplate of a listbox inside a custom control.

thanks in advance


Solution

  • okay, I chnaged where i assign the itemtemplate to the following and it now works:

    #Region "APPLY TEMPLATE"
        Public Overrides Sub OnApplyTemplate()
            MyBase.OnApplyTemplate()
    
            '' if template is not nothing then initialize controls and wire up the event handlers
            If Me.Template IsNot Nothing Then
    
                InitializeListbox()
                If ResultsListBox IsNot Nothing Then
                    OnItemSourceChanged(ItemsSource)
                    AddHandler ResultsListBox.KeyDown, AddressOf ResultListBox_KeyDown
                    AddHandler ResultsListBox.SelectionChanged, AddressOf ResultListBox_SelectionChanged
                    ResultsListBox.ItemTemplate = ItemTemplate
                    ResultsListBox.ItemsSource = ItemsSource
                End If
            End If
        End Sub
    #End Region