【问题标题】:Help understanding relationship of Resources/Styles/XAML files in Silverlight帮助理解 Silverlight 中资源/样式/XAML 文件的关系
【发布时间】:2009-06-05 00:33:52
【问题描述】:

我是 Silverlight 的新手,我想完成一个相对简单的任务:
创建一个显示标题和一些子内容的“面板”控件。

我能够在一定程度上完成这项工作,但 XAML 的放置确实让我感到困惑。

在我的页面上,我使用我的控件。这导致我的面板在子内容区域中显示一个蓝色按钮,顶部有一个 20 像素的黄色标题,上面写着“下面是一些内容”。

<UserControl x:Class="SilverlightApplication9.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:SilverlightApplication9">
    <Grid Background="White">        
        <local:MyPanel Background="Blue">            
                <Button Width="50" Height="25" Content="Hello"></Button>            
        </local:MyPanel>    
    </Grid>
</UserControl>

我的面板源码很简单,只是:

public partial class MyPanel : ContentControl
{
    public MyPanel()
    {
        DefaultStyleKey = typeof(MyPanel);   
        InitializeComponent();         
    }
}

这是一个部分类,并且有一个附加的 XAML 文件,这是我开始困惑的地方:

如果我尝试将我的样式/模板代码放入部分类 XAML 文件中,它似乎被忽略了(显示了我的按钮,但缺少颜色和文本等其他内容)

<ContentControl x:Class="SilverlightApplication9.MyPanel"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:SilverlightApplication9">
    <ContentControl.Resources>
        <ResourceDictionary>
            <Style TargetType="local:MyPanel">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="local:MyPanel">
                            <Grid Background="Yellow">
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="20" />
                                    <RowDefinition />
                                </Grid.RowDefinitions>
                                <TextBlock HorizontalAlignment="Center" Height="20" Grid.Row="0" Text="Below is some content"/>
                                <Grid Grid.Row="1" Background="LightBlue">
                                    <ContentPresenter />
                                </Grid>
                            </Grid>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </ResourceDictionary>
    </ContentControl.Resources>
</ContentControl>

但是,如果我创建一个 \Themes\generic.xaml 文件并粘贴相同的代码,它就可以工作

<ResourceDictionary 
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:local="clr-namespace:SilverlightApplication9"
  xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows"
  >
    <Style TargetType="local:MyPanel">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local:MyPanel">
                    <Grid Background="Yellow">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="20" />
                            <RowDefinition />
                        </Grid.RowDefinitions>
                        <TextBlock HorizontalAlignment="Center" Height="20" Grid.Row="0" Text="Below is some content"/>
                        <Grid Grid.Row="1" Background="LightBlue">
                            <ContentPresenter />
                        </Grid>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

我显然遗漏了有关如何在项目中处理或使用资源或 XAML 文件的重要信息(在 Silverlight 之前我没有任何 WPF 经验)。

我做错了什么导致我无法将面板的模板代码放入面板的 xaml 文件中?是否有一些关于 XAML 和资源的概念我弄错了?

【问题讨论】:

    标签: silverlight xaml resources


    【解决方案1】:

    David,您需要为您的样式创建一个键,并通过它的 Style 属性在面板中引用它...这是 Silverlight 的一个限制,它不允许您创建适用于所有样式的“全局”样式某种类型的元素。

    正如您所注意到的,当您将样式置于主题中时,这种行为会有所不同。

    另一种选择是将样式放在面板本身的 ResourceDictionary 中,而不是页面/用户控件中,但是您不能在其他面板中重复使用该样式。

    【讨论】:

    • 我注意到,当按主题完成时,它将覆盖父主题(即使我在页面中添加了类似 TwilightBlue 之类的内容,我面板内的按钮也会获得通用外观)。您能否扩展第三个选项,将样式放在“面板本身”的 ResourceDictionary 中 - 我不完全确定它是如何工作的。你的意思是把样式放到面板的每个实例中(这样样式就在按钮和其他子内容之前)?我还想最终添加一些行为 - 我是否应该通过重写 AddChild 方法来追求程序化方法?
    • 详细说明,我将放弃使用 Styles 和 xaml 的编程方法,而是通过在 cs 文件中手动创建子组件(如我的标题)来填充控件,然后覆盖设置内容的机制,以便将其放置在正确的子组件中。我实际上还没有尝试过上述任何方法,这似乎是另一种做我想做的事情的方式(我想创建少量面板,即带有标准标题的面板、对话框/窗口样式面板等)
    • 是的,每个元素都可以有自己的资源字典,所以样式会被放置到面板的每个实例中。我不建议使用编程方法,因为我更喜欢在视图和演示者或演示模型之间进行清晰的分离……我是模型-视图-视图模型模式的追随者。看来您应该能够仅通过 XAML 和数据绑定来完成您的任务。您是否考虑过使用现有元素之一(如网格或堆栈面板)并重写模板来创建您需要的内容,而不是创建自己的面板?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-30
    • 1970-01-01
    • 1970-01-01
    • 2011-07-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多