皮肤控制背景 - 更好的性能?

发布于 2025-01-04 19:03:47 字数 2308 浏览 0 评论 0原文

抱歉,如果这个问题过于简单,但我很难弄清楚如何创建控件背景 - 希望它能提高应用程序性能。

我有 9 个不同的控件。他们都是有背景的。背景由图像、其他控件或两者组成。所有这些背景都有另一个背景。

可以将其想象为具有幻灯片、幻灯片布局和幻灯片母版的 PowerPoint - 按此顺序继承。我有 9 个幻灯片/控件。

  • 前 3 个控件具有相同的“控件布局”(我们称之为 ControlLayout1)。 ControlLayout1ControlMaster1 获取一些元素。
  • 后 3 个控件也具有相同的控件布局,但它是 与第一个不同。我们将其称为ControlLayout2。它还 继承自ControlMaster1
  • 最后一组 3 个控件又有所不同。我们可以打电话给他们 ControlLayout3。但这一次,他们继承了不同的主人 - ControlMaster2

现在,在每个控件中,我每次都单独编写所有 XAML。我想一定有一种方法可以不把这些写在每一项中。理想情况下,我想要创建的是一组可以重用的 XAML。

这是一些伪 XAML:

<UserControl x:Name="Control1">
    <MyBackground (ControlLayout1)/>
</UserControl>

<UserControl x:Name="Control2">
    <MyBackground (ControlLayout2)/>
</UserControl>

<UserControl x:Name="Control3">
    <MyBackground (ControlLayout3)/>
</UserControl>

然后是 ControlLayouts 的某个地方(我不知道,比如 Application.Resources 或其他地方)

<Canvas x:Name="ControlLayout1">
    <MyMasterBackground (ControlMaster1)/>
</Canvas>

<Canvas x:Name="ControlLayout2">
    <MyMasterBackground (ControlMaster1)/>
    <TextBox Text="The Control 2">
</Canvas>

<Canvas x:Name="ControlLayout3">
    <MyMasterBackground (ControlMaster2)/>
    <TextBox Text="The Control 3">
</Canvas>

,然后是 ControlMasters

<Canvas x:Name="ControlMaster1">
    <Canvas.Background>
        <ImageBrush ImageSource="/Images/image1.jpg" />
    </Canvas.Background>
</Canvas>

<Canvas x:Name="ControlMaster2">
    <Canvas.Background>
        <ImageBrush ImageSource="/Images/image2.jpg" />
    </Canvas.Background>
    <TextBox Text="Control Master 1">
</Canvas>

一旦定义, ControlLayouts 和ControlMaster 永远不需要改变——它们是静态的。

如果我可以将这些全部放在一个位置并重用 XAML,那么除了拥有较小的 XAP 之外,我还希望我的应用程序的性能能够得到改善,因为 ControlLayouts 自动获取 BitmapCached 或类似的东西。

那么首先,是否有一个好的策略来实现上述内容(ControlLayouts 和 Masters 没有任何代码隐藏)?其次,加载Control1、Control2等时性能是否会提高?最后,如果它们是纯用户控件(即它们背后有一些代码),那么性能会更好吗?

提前致谢!

sorry if this question is overly simple, but I'm having a hard time figuring out how to create backgrounds to controls - in the hopes that it will improve app performance.

I have 9 different controls. All of them have a background. The backgrounds are made up of either images, other controls or both. All of those backgrounds have another background.

Think of this like Power Point with slides, slide layouts and slide masters - inherited in that order. I have 9 slides / controls.

  • The first 3 controls have the same "control layout" (let's call it
    ControlLayout1). ControlLayout1 gets some of it's elements from ControlMaster1.
  • The second 3 controls also have the same control layout, but it is
    different from the first. Let's call it ControlLayout2. It also
    inherits from ControlMaster1.
  • The final set of 3 controls are different again. We can call them
    ControlLayout3. But this time, they inherit from a different master - ControlMaster2.

Right now in each control I'm writing out all the XAML each time separately. I'm thinking there must be a way to not write these in each of these each item. Ideally, what I would like to create is one set of XAML that can be reused.

Here's some pseudo-XAML:

<UserControl x:Name="Control1">
    <MyBackground (ControlLayout1)/>
</UserControl>

<UserControl x:Name="Control2">
    <MyBackground (ControlLayout2)/>
</UserControl>

<UserControl x:Name="Control3">
    <MyBackground (ControlLayout3)/>
</UserControl>

And then somewhere for ControlLayouts (I don't know, like Application.Resources or elsewhere)

<Canvas x:Name="ControlLayout1">
    <MyMasterBackground (ControlMaster1)/>
</Canvas>

<Canvas x:Name="ControlLayout2">
    <MyMasterBackground (ControlMaster1)/>
    <TextBox Text="The Control 2">
</Canvas>

<Canvas x:Name="ControlLayout3">
    <MyMasterBackground (ControlMaster2)/>
    <TextBox Text="The Control 3">
</Canvas>

And then for the ControlMasters

<Canvas x:Name="ControlMaster1">
    <Canvas.Background>
        <ImageBrush ImageSource="/Images/image1.jpg" />
    </Canvas.Background>
</Canvas>

<Canvas x:Name="ControlMaster2">
    <Canvas.Background>
        <ImageBrush ImageSource="/Images/image2.jpg" />
    </Canvas.Background>
    <TextBox Text="Control Master 1">
</Canvas>

Once defined, the ControlLayouts and ControlMasters never need to change - they are static.

Beyond just having a smaller XAP if I can put these all in one location and reuse the XAML, I'm hoping performance will be improved in my app as the ControlLayouts automatically get BitmapCached or something like that.

So first, is there a good strategy to implement the above (the ControlLayouts and Masters do not have any code-behind)? Secondly will performance be improved in loading of Control1, Control2, etc.? Finally, if they were pure usercontrols (i.e. they had some code behind), would that be better for performance?

Thanks in advance!

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

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

发布评论

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

评论(1

玻璃人 2025-01-11 19:03:47

您要求的是几件事的组合:

关于背景事物:只需在 UserControl 后面的代码中创建 Brush 类型的依赖属性(让我们称之为 MyBackgroundDP),并将其绑定到您的 XAML,如下所示

<UserControl ...>
  <Grid Background={"Binding MyBackgroundDP, RelativeSource={RelativeSource Mode=FindAncestor, AncestoryType=UserControl}}">
     <!-- More XAML declarations -->
  </Grid>
</UserControl>

:依赖属性,您可以使用 Visual Studio 中内置的代码片段: propdp
只需写“propdp”和该 TAB 两次即可。填满字段,一切都很好。

好吧,这很容易,对吧? ;)

现在是更困难的部分:制作所谓的母版页。
其实和背景没多大区别。
声明另一个依赖属性,只是这次类型为对象或 FrameworkElement(更好)。

然后在 XAML 中声明一种占位符:ContentControl。我们将此示例称为 MyContentDP:

<UserControl ...>
  <Grid Background={"Binding MyBackgroundDP, RelativeSource={RelativeSource Mode=FindAncestor, AncestoryType=UserControl}}">
     <ContentControl ContentTemplate="{Binding MyContentDP, RelativeSource={RelativeSource Mode=FindAncestor, AncestoryType=UserControl}}" />
  </Grid>
</UserControl>

然后,您可以微调要在此“主视图”中提供的任何其他内容,在网格周围添加边框,放一些花,等等。

完成后,这就是您使用它的方式,假设它被称为 MyUserControl

<Window ...
       xmlns:local="...reference_to_your_usercontrol_dll/exe">
   <Grid>
      <local:MyUserControl MyBackgroundDP="Red">
         <local:MyUserControl.MyContentDP>
            <!-- More XAML declarations here -->
         </local:MyUserControl.MyContentDP>
      </local:MyUserControl>
   </Grid>
</Window>

现在的性能点:

如果您将其所有 XAML 作为自定义控件(与 UserControl 不同) ,然后您可以将所有 XAML 放入 App.xaml
为什么?因为解析 XAML 可能是一项密集型操作,如果您让 WP7/SL 在运行时需要时解析它,则会损失性能。
相反,您的 App.xaml 在启动时被解析,然后存储在内存中。这就是加载应用程序时所做的事情。您将获得性能提升,尽管对于由少量 XAML 组成的控件而言,性能提升很小,但这仍然是一个很好的做法。

希望这会有所帮助,

巴布。

What you ask for is a combination of a few things:

About the Background thing: just create a dependency property (let's call it MyBackgroundDP) of type Brush in the code behind of a UserControl, and bind it to your XAML like:

<UserControl ...>
  <Grid Background={"Binding MyBackgroundDP, RelativeSource={RelativeSource Mode=FindAncestor, AncestoryType=UserControl}}">
     <!-- More XAML declarations -->
  </Grid>
</UserControl>

To create the dependency property, you can use the built in snippet in visual studio: propdp
Simply write "propdp" and that TAB twice. Fill up the fields and it's all good.

Alright so that was easy enough, right? ;)

Now the tougher part: making so-called master pages.
Actually it's not that much different from the background thing.
Declare another dependency property, only this time of type object, or FrameworkElement (better).

Then in your XAML, you declare a kind of placeholder: ContentControl. Let's call it MyContentDP for this example:

<UserControl ...>
  <Grid Background={"Binding MyBackgroundDP, RelativeSource={RelativeSource Mode=FindAncestor, AncestoryType=UserControl}}">
     <ContentControl ContentTemplate="{Binding MyContentDP, RelativeSource={RelativeSource Mode=FindAncestor, AncestoryType=UserControl}}" />
  </Grid>
</UserControl>

You can then fine tune whatever else you want to provide in this "master view", add a border around the Grid, put some flowers, you name it.

Once you're done, this is how you use it, assuming it was called MyUserControl

<Window ...
       xmlns:local="...reference_to_your_usercontrol_dll/exe">
   <Grid>
      <local:MyUserControl MyBackgroundDP="Red">
         <local:MyUserControl.MyContentDP>
            <!-- More XAML declarations here -->
         </local:MyUserControl.MyContentDP>
      </local:MyUserControl>
   </Grid>
</Window>

Now the performance point:

If you put all the XAML for this as a Custom control (which is DIFFERENT from a UserControl), you can then put all the XAML in your App.xaml
Why? because parsing XAML can be an intensive operation, and if you make WP7/SL parse it at runtime whenever you need it, you lose performance.
Instead, your App.xaml gets parsed at startup, then it's in memory. That's what's done in the loading of your application. You would get a performance boost, although it would be minimal for controls made of few XAML, it is still a good practice.

Hope this helps,

Bab.

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