Silverlight默认样式问题

发布于 2024-08-03 19:30:48 字数 363 浏览 5 评论 0原文

我有以下场景:

  1. 创建一个名为 Lib1 的新类库项目 1.1.添加一个名为 control1 的新控件,Themes/generic.xaml 文件并指定 control1的默认样式。
  2. 创建一个名为 lib2 的新类库项目。 2.1.添加一个名为control2的新控件,Themes/generic.xaml文件并指定 control2的默认样式。在 control2 的 dafaultStyle 中,我使用 control1。

我的问题是:我是否必须将 control1 的 defaultStyle xaml 复制/粘贴到 lib2 的 generic.xaml,使用 control1 并在 control2 中应用其样式?

I have the following scenario:

  1. Create a new class library project called Lib1
    1.1. Add a new control called control1, Themes/generic.xaml file and specify
    the default style of control1.
  2. Create a new class library project called lib2.
    2.1.Add a new control called control2, Themes/generic.xaml file and specify
    the default style of control2. In the dafaultStyle of control2 I use control1.

My question is: Do I have to copy/paste the defaultStyle xaml of control1 into the
generic.xaml of lib2, to use control1 with its style applied in control2?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

猫瑾少女 2024-08-10 19:30:48

Control 的默认样式查找始终在定义该 Control 的程序集中完成。因此,如果 Control1 在 Lib1.dll 中定义,则将始终在 Lib1.dll 的 generic.xaml 中查找默认样式。从哪里使用控件并不重要。

The default style lookup for a Control is always done in the assembly that the Control is defined in. So if Control1 is defined in Lib1.dll, the default style will always be looked for in generic.xaml in Lib1.dll. It doesn't matter where the Control is being used from.

乖乖 2024-08-10 19:30:48

为了确保我正确理解您的答案,我将用自己的话重述:

  1. 您想要一个 Silverlight 课程
    包含控件的库(Lib1)
    (控制1)。
  2. 你想拥有一个
    Silverlight 类库 (Lib2)
    其中包含一个控件(Control2)。
  3. 您希望控件将其各自的 generic.xaml 文件用于各自的控件样式。
  4. Control2 将在其样式定义中包含 Control1,而不在 Lib2 的 generic.xaml 文件中重新定义其样式。

如果这是正确的,我将在下面描述我的答案:

是的,这是可能的,正如 Keith Mahoney 所说 此处。我将详细介绍他的答案并举一个例子。

每个 Silverlight 类库在编译时都会生成一个动态链接库 (dll)。所有类(控件)和资源(样式)都包含在这些 dll 中。因此,当您创建一个包含其中包含的控件的样式资源的 lib1 类库时,它将全部存储在 lib1 dll 中。

以下是我的解决方案示例:


设置解决方案:

首先,我创建了新的解决方案(StackOverflow Example.sln)。然后我向 Silverlight 类库(Lib1 1.1)类型的解决方案添加了一个新项目。请注意,Silverlight 并不总是能很好地处理命名空间中的空格,因此您可能需要(像我一样)将命名空间重命名为 Lib1。有关如何执行此操作的详细信息,请参阅“操作方法”部分。接下来,我将第二个项目添加到 Silverlight 类库 (Lib2 2.1) 类型的解决方案中。我再次将该项目的根命名空间更改为不带空格的根命名空间。最后,我向我的解决方案添加了一个 Silverlight 应用程序项目 (SLApplication)。请注意,在添加 Silverlight 应用程序项目时,系统会提示您向项目中添加 Web 项目或网页以创建 Silverlight 控件。任一选项都有效,请使用最适合您情况的选项。我使用了单独的网站选项(默认)。现在,当我们设置两个类库时,我们得到了一个默认的启动器 class1.vb 文件。让我们在解决方案资源管理器中将这些文件重命名为 Control1.vb(对于 Lib1 1.1)和 Control2.vb(对于 Lib2 2.1)。当我们这样做时,Visual Studio 2008 会询问我们是否希望重命名该类以匹配这个新名称,单击“是”。接下来,让我们弄清楚如何为每个控件设置主题。


设置主题:

我将从第一个控件库(Lib1 1.1)开始。首先,在项目根目录下新建一个文件夹;将其命名为“主题”(大小写无关紧要)。在此文件夹下,添加一个 xml 类型的新项目并将其命名为 generic.xaml。有关如何执行此操作的帮助,请参阅“操作方法”部分。打开 generic.xaml 文件(如果尚未打开)。删除自动插入的 xml 声明文本,并使用以下内容作为初始定义:

<ResourceDictionary
 xmlns="http://schemas.microsoft.com/client/2007"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <!-- Styles go here. -->    

</ResourceDictionary>

现在,由于我们的 Control1 控件位于此类库中,因此我们需要添加一个 xml 命名空间声明 (xmlns) (http://en.wikipedia.org/wiki/XML_namespace - 抱歉,关于非链接,我的代表需要是更高。)到我们的 generic.xaml 文件。为此,请在顶部声明中的大于符号 (>) 之前添加以下行: xmlns:lib1="clr-namespace:Lib1"。一旦完成,我们就可以布局一个简单的样式。请注意,我们将默认背景颜色设置为“红色”,以区分这两个控件。 Control1的简单样式请见下图:

<ResourceDictionary 
 xmlns="http://schemas.microsoft.com/client/2007"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 xmlns:lib1="clr-namespace:Lib1">

 <!-- Style for Control1 -->
 <Style TargetType="lib1:Control1">
  <Setter Property="Background" Value="Red" />
  <Setter Property="Template">
   <Setter.Value>
    <ControlTemplate TargetType="lib1:Control1">
     <Grid x:Name="LayoutGrid" Background="{TemplateBinding Background}">
      <TextBlock Text="Control 1" />
     </Grid>
    </ControlTemplate>
   </Setter.Value>
  </Setter>

 </Style>

</ResourceDictionary>

让我们从 Control2 开始。这与之前的 Lib1 1.1 声明非常相似。如果您尚未执行此操作,请像对第一个库 (Lib1 1.1) 所做的那样添加 Themes 文件夹和 generic.xaml 文件。现在,对于该项目,您将需要 Lib1 1.1 项目的引用。如果您需要帮助来执行此操作,请参阅“操作方法”部分。引用此文件后,打开 generic.xaml 文件(如果尚未打开)。该文件的定义几乎相同;但是,我们还将引用其他项目的命名空间。见下文:

<ResourceDictionary 
 xmlns="http://schemas.microsoft.com/client/2007"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 xmlns:lib2="clr-namespace:Lib2"
 xmlns:lib1="clr-namespace:Lib1;assembly=Lib1">

    <!-- Styles go here. --> 

</ResourceDictionary>

请注意,现在我们不仅引用我们自己的命名空间 (lib2),而且还在 xml 命名空间声明中引用其他控件的命名空间 (lib1)。另请注意,在非本地控件库中,我们还必须引用程序集名称。由于我们想要使用 lib one 中的控件(及其样式),因此我们需要在该项目中找到一个位置来使用它。为此,我设置了一个网格,每个控件都有单独的行。请注意,我们将默认背景颜色设置为“蓝色”,以区分这两个控件。 Control2的定义请参见下面:

<ResourceDictionary 
 xmlns="http://schemas.microsoft.com/client/2007"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 xmlns:lib2="clr-namespace:Lib2"
 xmlns:lib1="clr-namespace:Lib1;assembly=Lib1">

 <!-- Style for Control2 -->
 <Style TargetType="lib2:Control2">
  <Setter Property="Background" Value="Blue" />
  <Setter Property="Template">
   <Setter.Value>
    <ControlTemplate TargetType="lib2:Control2">
     <Grid x:Name="LayoutGrid">
      <Grid.RowDefinitions>
       <RowDefinition />
       <RowDefinition />
      </Grid.RowDefinitions>

      <lib1:Control1 Grid.Row="0" />

      <Grid x:Name="Control2" Grid.Row="1" Background="{TemplateBinding Background}">
       <TextBlock Text="{TemplateBinding Text}" />
      </Grid>
     </Grid>
    </ControlTemplate>
   </Setter.Value>
  </Setter>
 </Style>
</ResourceDictionary>

这只是表明了我们想要有样式的事实。现在我们需要告诉 Silverlight 我们希望将这些样式应用于我们的控件。


使用主题:

在我们的类中,我们必须告诉 Silverlight 这些将是自定义用户控件,为此,我们需要从 Control 继承(或任何其他 UIElement 控件 - 对于本示例,我们将保持简单并使用 Control)。为了告诉控件使用 generic.xaml 中定义的样式,我们需要在每个控件的构造函数中执行此操作。

对于 Control1:

公共子 New()
MyBase.DefaultStyleKey = GetType(Control1)
结束子

Control2 的

:公共子 New()
MyBase.DefaultStyleKey = GetType(Control2)
结束子

现在我们要做的就是告诉我们的网站使用我们的新控件(Control2)。


设置 Web 应用程序:

您将需要从您的 Web 项目引用这两个类库。有关如何执行此操作的详细信息,请参阅“操作方法”部分。打开 Web 应用程序项目 (SLApplication) 中的 Page.xaml 文件。你的默认值应该是这样的:

<UserControl x:Class="SLApplication.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Width="400" Height="300">
    <Grid x:Name="LayoutRoot" Background="White">

 </Grid>
</UserControl>

我们将向其中添加 Silverlight 类库 (Lib2 2.1) 的 xml 命名空间声明,以便我们可以引用 Control2。现在我们已经引用了我们的类库,我们可以使用其中声明的任何控件。如果您在将名称空间添加到 xmlns 声明后尝试使用名称空间而不进行构建,则可能看不到其中任何声明的类(控件)。要解决此问题,请构建一次。另请注意,Visual Studio 2008 有时对自定义库感到奇怪,并且可能会生成错误,指出自定义库未定义。通过重新启动解决方案(关闭 Visual Studio 并重新打开)可以修复此问题。显示 Control2(包含 Control1)的最终代码如下:

<UserControl x:Class="SLApplication.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
 xmlns:lib2="clr-namespace:Lib2;assembly=Lib2"
    Width="400" Height="300">
    <Grid x:Name="LayoutRoot" Background="White">
  <lib2:Control2 />
 </Grid>
</UserControl>

现在构建并运行。如果一切顺利,您应该看到以下内容:

屏幕截图 http://www.imagefrog.n​​et/out.php/i40631_StackOverflowExample.jpg< /a>

完整的项目可以从 Google Code 下载:
http://code.google.com/p/stackoverflow- answers-by-scott/wiki/1366075

压缩源:
http://stackoverflow-answers-by-scott.googlecode.com/ files/1366075.zip

尽情享受吧!


操作方法:

更改项目命名空间

在解决方案资源管理器中,展开要更改命名空间的项目,然后双击“我的项目”。对于 Silverlight 类库项目,左侧​​将有四个选项卡,其中之一是“Silverlight”。如果尚未选择此选项卡,请选择它。在“根命名空间”文本框下,将命名空间更改为您所需的命名空间。

将“generic.xaml”添加到项目

中 在解决方案资源管理器中,右键单击项目名称。单击“添加”,然后单击“新文件夹”。这将在项目的根目录下创建一个文件夹。将此文件夹命名为“主题”。请注意,这里大小写并不重要。右键单击“主题”文件夹,单击“添加”,然后单击“新建项目...”。将出现一个对话框,供您选择要添加的项目类型。单击“模板”部分下的“XML 文件”。将名称字段(位于对话框底部)下的名称更改为 generic.xaml。单击添加。

创建项目引用

要创建项目引用,请右键单击需要引用的项目。从菜单中选择“添加参考...”。将显示一个对话框,供您选择要添加的参考。选择该对话框顶部的“项目”选项卡。选择所需的项目参考。如果在此列表中没有看到要引用的项目,请检查是否已将该项目添加到解决方案中。


Just to make sure I understand your answer correctly, I will restate it in my own words:

  1. You want to have a Silverlight class
    library (Lib1) that houses a control
    (Control1).
  2. You want to have a
    Silverlight class library (Lib2)
    that houses a control (Control2).
  3. You want to have the control use their respective generic.xaml files for respective control styles.
  4. Control2 is to include Control1 in its style definition, without redefining its style in the generic.xaml file from Lib2.

If this is correct, I will describe my answer below:

Yes, this is possible as Keith Mahoney said here. I will go into detail on his answer and an example.

Each Silverlight class library generates a Dynamic-link library (dll) when compiled. All the classes (controls) and resources (styles) are contained in these dll's. Thus, when you create a lib1 class library with a style resource for a control contained within, it will all be stored in the lib1 dll.

Below is my example of the solution:


Setting up the solution:

First, I created new solution (StackOverflow Example.sln). Then I added a new project to the solution of type Silverlight Class Library (Lib1 1.1). Please note that Silverlight does not always play nicely with spaces in the namespace, so you may want to (as I did) rename the namespace to Lib1. See "How-To's" section for details on how to do this. Next I added the second project to the solution of type Silverlight Class Library (Lib2 2.1). I again, changed the root namespace of this project to one without spaces. Finally, I added a Silverlight Application project to my solution (SLApplication). Please note that in adding the Silverlight application project, you will be prompted to add a web project or web page to your project for creating the Silverlight control. Either option will work, please use the best for your situation. I used the separate website option (default). Now, when we setup the two class libraries, we were given a default starter class1.vb file. Let's rename these file to Control1.vb (for Lib1 1.1) and Control2.vb (for Lib2 2.1) in the solution explorer. When we do this, Visual Studio 2008 asks us if we'd like it to rename the class to match this new name, Click 'Yes'. Next up, let's figure out how to setup the themes for each of our controls.


Setting up themes:

I will start with the first control library (Lib1 1.1). First, create a new folder under the root of the project; name it "Themes" (case doesn't matter). Under this folder, add a new item of type xml and name it generic.xaml. For help on how to do this, see the "How-To's" section. Open the generic.xaml file, if it isn't already open. Delete the xml declaration text that was automatically inserted for you, and use the following for your initial definition:

<ResourceDictionary
 xmlns="http://schemas.microsoft.com/client/2007"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <!-- Styles go here. -->    

</ResourceDictionary>

Now, since our Control1 control lives in this class library, we will need to add an xml namespace declaration (xmlns) (http://en.wikipedia.org/wiki/XML_namespace -sorry about the non link, my rep needs to be higher.) to our generic.xaml file. To do this, add the following line: xmlns:lib1="clr-namespace:Lib1" before the grater than symbol (>) in the top declaration. Once this is done, we can layout a simple style. Please note that we're setting the default background color to "Red" in order to differentiate the two controls. Please see below for the simple style for Control1:

<ResourceDictionary 
 xmlns="http://schemas.microsoft.com/client/2007"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 xmlns:lib1="clr-namespace:Lib1">

 <!-- Style for Control1 -->
 <Style TargetType="lib1:Control1">
  <Setter Property="Background" Value="Red" />
  <Setter Property="Template">
   <Setter.Value>
    <ControlTemplate TargetType="lib1:Control1">
     <Grid x:Name="LayoutGrid" Background="{TemplateBinding Background}">
      <TextBlock Text="Control 1" />
     </Grid>
    </ControlTemplate>
   </Setter.Value>
  </Setter>

 </Style>

</ResourceDictionary>

With this let's start with the Control2. This will be very similar to the previous declaration for Lib1 1.1. If you haven't already done so, please add the Themes folder and the generic.xaml file as you did for the first library (Lib1 1.1). Now, for this project, you will need a reference to the Lib1 1.1 project. If you need help doing this, please see the "How To's" section. Once this is referenced, open the generic.xaml file, if it isn't already open. The definition of this file is almost identical; however, we will also be referencing the other projects namespace as well. See below:

<ResourceDictionary 
 xmlns="http://schemas.microsoft.com/client/2007"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 xmlns:lib2="clr-namespace:Lib2"
 xmlns:lib1="clr-namespace:Lib1;assembly=Lib1">

    <!-- Styles go here. --> 

</ResourceDictionary>

Notice that now we are not only referencing our own namespace (lib2) but also referencing the other control's namespace (lib1) in the xml namespace declaration. Also notice that in the non-local control library, we also must reference the assembly name. Since we want to use the control (and its style) from lib one, we will need a place to use it in this project. For this, I have setup a grid with separate rows for each control. Please note that we're setting the default background color to "Blue" in order to differentiate the two controls. Please see below for Control2's definition:

<ResourceDictionary 
 xmlns="http://schemas.microsoft.com/client/2007"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 xmlns:lib2="clr-namespace:Lib2"
 xmlns:lib1="clr-namespace:Lib1;assembly=Lib1">

 <!-- Style for Control2 -->
 <Style TargetType="lib2:Control2">
  <Setter Property="Background" Value="Blue" />
  <Setter Property="Template">
   <Setter.Value>
    <ControlTemplate TargetType="lib2:Control2">
     <Grid x:Name="LayoutGrid">
      <Grid.RowDefinitions>
       <RowDefinition />
       <RowDefinition />
      </Grid.RowDefinitions>

      <lib1:Control1 Grid.Row="0" />

      <Grid x:Name="Control2" Grid.Row="1" Background="{TemplateBinding Background}">
       <TextBlock Text="{TemplateBinding Text}" />
      </Grid>
     </Grid>
    </ControlTemplate>
   </Setter.Value>
  </Setter>
 </Style>
</ResourceDictionary>

This just sets up the fact that we want to have styles. We now need to tell Silverlight that we want these styles to be applied to our controls.


Using themes:

In our classes, we have to tell Silverlight that these are going to be custom user controls, to do this, we need to inherit from Control (or any other UIElement control - for this example, we will stay simple, and use Control). In order to tell the control to use a style defined in the generic.xaml, we need to do this in our constructor of each control.

For Control1:

Public Sub New()
MyBase.DefaultStyleKey = GetType(Control1)
End Sub

For Control2:

Public Sub New()
MyBase.DefaultStyleKey = GetType(Control2)
End Sub

Now all we have to do now, is tell our web site to use our new control(Control2).


Setting up the WebApplication:

You will need to reference both class libraries from your web project. See "How-To's" section for details on how to do this. Open up the Page.xaml file in your web application project (SLApplication). Your default should look something like this:

<UserControl x:Class="SLApplication.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Width="400" Height="300">
    <Grid x:Name="LayoutRoot" Background="White">

 </Grid>
</UserControl>

We will add to this the xml namespace declaration for our Silverlight class library (Lib2 2.1) so that we may reference Control2. Now that we have referenced our class library, we can use any controls that are declared within. If you try to use the namespace without building after you add it to your xmlns declaration, you may not see any declared classes (controls) within. To fix this, build once. Please also note, that Visual Studio 2008 is sometimes weird about custom libraries, and may generate an error that says the custom library is not defined. This is fixed with a re-launch of the solution (Close Visual Studio and reopen). The final code to show the Control2 (which contains Control1) is as follows:

<UserControl x:Class="SLApplication.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
 xmlns:lib2="clr-namespace:Lib2;assembly=Lib2"
    Width="400" Height="300">
    <Grid x:Name="LayoutRoot" Background="White">
  <lib2:Control2 />
 </Grid>
</UserControl>

Now build, and run. If everything went well, you should see the following:

Screen Shot http://www.imagefrog.net/out.php/i40631_StackOverflowExample.jpg

The full project can be downloaded from Google Code:
http://code.google.com/p/stackoverflow-answers-by-scott/wiki/1366075

Zipped source:
http://stackoverflow-answers-by-scott.googlecode.com/files/1366075.zip

Enjoy!


How-To's:

Change project namespace

In the solution explorer expand the project on which you want to change the namespace, and double click on the "My Project". For Silverlight class library projects, you will have four tabs on the left, one of which is "Silverlight". Select this tab, if it is not already selected. Under the "Root namespace" textbox, change the namespace to your desired namespace.

Add 'generic.xaml' to project

In the solution explorer, right click on the project name. Click "Add", and then click "New Folder". This will create a folder under the root of the project. Name this folder "themes". Please note that case does not matter here. Right click on the "themes" folder, click "Add", then click "New Item...". A dialog box appears for you to select what item type you want to add. Click "XML File" under the Templates section. Change the name to generic.xaml under the name field (at the bottom of the dialog). Click Add.

Create a project reference

To create a project reference, right click on the project that needs the reference. Select "Add Reference..." from the menu. A dialog box will be displayed for you to choose the reference to add. Select the "Projects" tab at the top of this dialog. Select the desired project reference. If you do not see the project that you want to reference in this list, check that you have added the project to the solution.


~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文