了解样式和模板在Silverlight中的工作方式

时间:2011-05-19 07:10:31

标签: silverlight coding-style

我正在努力了解样式在silverlight中是如何工作的,这就是我所做的:

<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>

正确显示文本和图像,请注意test.png是我项目根目录下的资源文件。

首先我不明白:为什么我的图像在运行时正确显示,而不是在visual studio中设计?

然后,我想在我的风格中使用数据表值,所以我使用:

<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>

好的,它正常工作,我的viewmodel将test.png作为亲戚公开了一个Uri。 我现在想做的是使用带有许多图像的按钮,所以能够做到这样的事情本来是很棒的:

<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="{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>

但属性TheUrl当然不存在于按钮中。 我不想创建自己的控件,目的是了解样式。

我该怎么做?

提前感谢您的帮助。 最好的问候

1 个答案:

答案 0 :(得分:1)

你的观察结果是正确的,按钮没有TheUrl属性。你必须在这里选择。一种是使用Button的Tag属性:

<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>

顺便说一下,我不会绑定到Width / Height属性,这些属性可能没有明确设置。而是绑定到ActualHeight和ActualWidth,您可以保证始终设置它。

Tag是object类型的属性,可用于一般可扩展性。另一个更优雅的选择是定义附加属性。请参阅以下博客文章中的教程:

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