Custom Controls and Styles

Jul 26, 2013 at 2:08 PM
I have a custom AutoCompleteBoxEx which derives from AutoCompleteBox (WPF Toolkit) and forces the text to upper case.
Which I use it on a UserControl

...
<pcontrols:AutoCompleteComboEx .x:Name="Supplier" " ItemsSource="{Binding Suppliers}" ...>

The default combo theme style is not being used, is there any magical I need to do to utilise the default combox Mordern UI style.
Jul 26, 2013 at 5:22 PM
At the end of the day, you have to create your own style, but... If there's an existing style that's at least pretty close it could be fairly easy. Here's an example of a CapText control, just enforces all letters be upper case.
Public Class CapText
    Inherits TextBox
    Private Sub CapText_TextChanged(sender As Object, e As TextChangedEventArgs) Handles Me.TextChanged
        If Text <> UCase(Text) Then
            Dim ss = SelectionStart
            Dim sl = SelectionLength
            Text = UCase(Text)
            SelectionStart = ss
            SelectionLength = sl
        End If
    End Sub
End Class
You can do your styling on page or in loose xaml. If you do a loose xaml file you'll have to merge it also when changing the style.

Here's a page using that control:
<UserControl
             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" 
                         xmlns:mui="http://firstfloorsoftware.com/ModernUI"
             xmlns:local="clr-namespace:DemoAppMUI" x:Class="CustomControl" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <UserControl.Resources>
        <Style TargetType="{x:Type local:CapText}"  BasedOn="{StaticResource {x:Type TextBoxBase}}"  />
    </UserControl.Resources>
    <Grid>

        <local:CapText HorizontalAlignment="Left" Margin="55,43,0,0" TextWrapping="Wrap" Text="CapText" VerticalAlignment="Top" Width="136"/>
        <local:CapText HorizontalAlignment="Left" Margin="55,70,0,0" TextWrapping="Wrap" Text="CapText" VerticalAlignment="Top" Width="136"/>
        <local:CapText HorizontalAlignment="Left" Margin="55,97,0,0" TextWrapping="Wrap" Text="CapText" VerticalAlignment="Top" Width="136"/>

    </Grid>
</UserControl>
Jul 27, 2013 at 9:01 AM
I think what I'm trying to say, I have the AutocompleteCombox working fine, but it doesn't pick up the default ComboBox style from MUI.
In fact this goes for any inherited controls that you create.

For example if you inherit from a TextBox call it TextBoxEx and then use it in your page.xaml the TextBoxEx doesn't pick up the style for the default MUI textbox.

I know I can copy the style from Modern UI source code and use it locally i.e. in my resources.xaml file it works. But I feel this isn't the correct approach.
Jul 27, 2013 at 4:50 PM
Edited Jul 27, 2013 at 4:55 PM
If you create a new visual control you have to style it. If you don't add new visual elements, you can base your new style off the existing control and be done.

If you are not visually changing a control an alternative would be to put it in a container. Since all the visual components are standard controls, existing styling will work.
' You have to write a style
Class MyCombo
    Inherits ComboBox
    ' Other Code
End Class
' you don't need a style
Class MyCombo
  Inherits Grid
    Private _myCombo as New ComboBox
    Sub New()
        InitializeComponent()
        Children.Add(_myCombo)
    End Sub
    ' Other Code
End Class
Jul 29, 2013 at 11:40 AM
I've manage to create a solution, seems the WPF Toolkit Autocompletecobox inherits from a Control, that was my first problem and then it was creative style got me this working....
<Style x:Key="ComboBoxStyle"  TargetType="controls:AutoCompleteComboEx">
    <Setter Property="IsTabStop" Value="False" />
    <Setter Property="Padding" Value="2" />
    <Setter Property="BorderThickness" Value="1" />
    <Setter Property="BorderBrush" Value="{DynamicResource InputBorder}"/>
    <Setter Property="Foreground" Value="{DynamicResource InputText}"/>
    <Setter Property="Background" Value="{DynamicResource InputBackground}"/>
    <Setter Property="MinWidth" Value="45" />
    <Setter Property="Template">
        <Setter.Value>


            <ControlTemplate TargetType="controls:AutoCompleteComboEx">
                <Grid Opacity="{TemplateBinding Opacity}">
                    <TextBox Padding="0" Background="{TemplateBinding Background}" IsTabStop="True" x:Name="Text" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" Foreground="{DynamicResource InputText}" Margin="0" />
                    <Popup x:Name="Popup">
                        <Grid Opacity="{TemplateBinding Opacity}">
                            <Border x:Name="PopupBorder" HorizontalAlignment="Stretch" BorderThickness="0" Background="{DynamicResource InputBackground}" >
                                <Border.RenderTransform>
                                    <TranslateTransform X="1" Y="1" />
                                </Border.RenderTransform>
                                <Border HorizontalAlignment="Stretch" Opacity="1.0" Padding="0" Background="{DynamicResource InputBackground}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" CornerRadius="0">
                                    <Border.RenderTransform>
                                        <TransformGroup>
                                            <TranslateTransform X="-1" Y="-1" />
                                        </TransformGroup>
                                    </Border.RenderTransform>
                                    <ListBox x:Name="Selector" ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Auto" ItemContainerStyle="{TemplateBinding ItemContainerStyle}" Background="{DynamicResource InputBackground}" Foreground="{DynamicResource InputText}" BorderThickness="0" ItemTemplate="{TemplateBinding ItemTemplate}" />
                                </Border>
                            </Border>
                        </Grid>
                    </Popup>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>