WPF Controls are lookless

Hello everybody,

today I want to drop a note about WPF controls. For me it was very shoking to discover that WPF controlls are lookless ( that's official term from Microsoft ). That sounds countr-intuitive. Especially if you make code like this:

<Window x:Class="Lookless.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Lookless"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Button Width="75" Height="24">
            _Click me!
        </Button>
        
    </Grid>
</Window>

and after execution you'll see form with a button. But don't be in hurry with conclusion. For this demo I'll use properties element syntax.

<Button Width="75" Height="24">
            <Button.Template>
                <ControlTemplate TargetType="Button">
 
                </ControlTemplate>
            </Button.Template>

Part before dot XAML interprets as class name, and after dot as property name. In this way we've told to button, please instead of default template, apply another. You may also wonder, why inside of ControlTemplate I need to mention TargetType. One of the reasons is that TargetType or if to be more clear Control templates can be implemented ( and often will be ) in some other file, so for such a case you need to point directly what is target type for template.

Full version of code now looks like this:

<Window x:Class="Lookless.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Lookless"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Button Width="75" Height="24">
            <Button.Template>
                <ControlTemplate TargetType="Button">
 
                </ControlTemplate>
            </Button.Template>
            _Click me!
        </Button>
        
    </Grid>
</Window>

After execution you see just empty form. That will be natural look of the button. Formless or invisible. Now let's make button Elliptic

<Button Width="75" Height="24">
            <Button.Template>
                <ControlTemplate TargetType="Button">
                    <Ellipse Height="22" Width="60" Fill="BlanchedAlmond"></Ellipse>
                </ControlTemplate>
            </Button.Template>
            _Click me!
        </Button>

Such a code will give following form:

as you can see, we have ellipsing button.

Let's make life harder. Suppose you want your button to have a color of background form. How to achieve it? Let's say we set Background color to be Green. You can do this with usage of special syntax of property binding one more time. Take a look:

<Grid>
        <Button Width="75" Height="24" Background="CornflowerBlue">
            <Button.Template>
                <ControlTemplate TargetType="Button">
                    <Ellipse Height="22" Width="60" Fill="{TemplateBinding Background}"></Ellipse>
                </ControlTemplate>
            </Button.Template>
            _Click me!
        </Button>
        
    </Grid>

And also comment with picture:

Curly brackets are named mark-up extension. It's very similar to what is done in AngularJS. Mark-up properties is something that says how properties will be set during run-time. 

this line 

"{TemplateBinding Background}"

says that you want to create instance of TemplateBinding class, and Background is passed as constructive parameter and WPF expect it to derive from certain base class ( mark-up extension ). 

Now let's say we want to add rectangle and text into our button. 

For this purpose you can use following XAML:

<Grid>
        <Button Width="225" Height="72" Background="CornflowerBlue">
            <Button.Template>
                <ControlTemplate TargetType="Button">
                    <Grid>
                        <Ellipse Width="120" Height="40" Fill="{TemplateBinding Background}"></Ellipse>
                        <Ellipse Width="40" Height="20" Fill="Green"></Ellipse>
                        <ContentPresenter Content="{TemplateBinding Content}"
                             HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                             VerticalAlignment="{TemplateBinding VerticalContentAlignment}"></ContentPresenter>
                        
                    </Grid>
                </ControlTemplate>
            </Button.Template>
            Inside Button Text
        </Button>
    </Grid>

Such a code will give you following window:

having all of this knowledge, you can now make buttons as well as other elements in WPF to look as you really like them to look and have any kind of shape. 

No Comments

Add a Comment