开发者

Understanding how styling and templating work in Silverlight

开发者 https://www.devze.com 2023-03-07 10:27 出处:网络
I\'m trying to understand how styles works in silverlight, this is what I\'ve done : <UserControl x:Class=\"SilverlightApplication1.MainPage\"

I'm trying to understand how styles works in silverlight, this is what I've done :

<UserControl x:Class="SilverlightApplication1.MainPage"
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:vm="clr-namespace:SilverlightApplication1" mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">

<UserControl.DataContext>
    <vm:ViewModel />
</UserControl.DataContext>

<UserControl.Resources>
    <Style x:Key="TestStyle" TargetType="Button">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Button">
                    <Image Source="test.png" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" />
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</UserControl.Resources>

<StackPanel x:Name="LayoutRoot" Background="White">
    <TextBlock Text="{Binding SayHello}" />
    <Button Style="{StaticResource TestStyle}" Width="100" Height="100 />
</StackPanel>

The text and the image are displayed correctly, note that test.png is a resource file at the root of my projet.

First thing I don't understand : why is my image correctly displayed at runtime, but not at design in visual studio ?

Then, I would like to use a databinded value in my style, so I use :

<UserControl x:Class="SilverlightApplication1.MainPage"
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:vm="clr-namespace:SilverlightApplication1" mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">

<UserControl.DataContext>
    <vm:ViewModel />
</UserControl.DataContext>

<UserControl.Resources>
    <Style x:Key="TestStyle" TargetType="Button">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Button">
                    <Image Source="{Binding MyUrl}" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" />
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</UserControl.Resources>

<StackPanel x:Name="LayoutRoot" Background="White">
    <TextBlock Text="{Binding SayHello}" />
    <Button Style="{StaticResource TestStyle}" Width="100" Height="100" />
</StackPanel>

Ok, it's working, my viewmodel exposes an Uri with the test.png as relative. What I would like to do now is to use the button with many images, so it could have been great to be able to do something like this :

<UserControl x:Class="SilverlightApplication1.MainPage"
xmln开发者_如何转开发s="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:vm="clr-namespace:SilverlightApplication1" mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">

<UserControl.DataContext>
    <vm:ViewModel />
</UserControl.DataContext>

<UserControl.Resources>
    <Style x:Key="TestStyle" TargetType="Button">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Button">
                    <Image Source="{TemplateBinding TheUrl}" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" />
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</UserControl.Resources>

<StackPanel x:Name="LayoutRoot" Background="White">
    <TextBlock Text="{Binding SayHello}" />
    <Button Style="{StaticResource TestStyle}" Width="100" Height="100" TheUrl="{Binding MyUrl}" />
</StackPanel>

but the property TheUrl of course doesn't exists in the button. I don't want to create my own control, the purpose is to understand styles.

How can I do this ?

Thanks in advance for any help. Best regards


you are correct in your observation that button does not have a TheUrl property. You have to options here. One is to use the Tag property of Button:

<UserControl.Resources>
    <Style x:Key="TestStyle" TargetType="Button">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Button">
                    <Image Source="{TemplateBinding Tag}" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" />
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</UserControl.Resources>

<StackPanel x:Name="LayoutRoot" Background="White">
    <TextBlock Text="{Binding SayHello}" />
    <Button Style="{StaticResource TestStyle}" Width="100" Height="100" Tag="{Binding MyUrl}" />
</StackPanel>

As an aside, I would not bind to the Width / Height properties, these may not be set explicitly. Instead, bind to ActualHeight and ActualWidth which you can guarantee will always be set.

Tag is a property of type object which can be used for general extensibility. The other, more elegant option is to define an attached property. See the tutorial in the following blog post:

http://www.hardcodet.net/2009/01/create-wpf-image-button-through-attached-properties

0

精彩评论

暂无评论...
验证码 换一张
取 消