Expression Blend & Silverlight 中的 ListBox 样式(第 2 部分 - ControlTemplate)





5.00/5 (23投票s)
在小型 MVVM 应用程序中如何为 ListBox 的 ControlTemplate 设置样式。
引言
欢迎来到我的Expression Blend & Silverlight的第 6 篇初学者教程。
这次,我们将重点关注 ListBox
的基本 Template
,即控件模板!
同时,通过调整周围元素使其更美观,为 ListBox
提供上下文。
现在我们已经处理了 ScrollBars
,可以正式处理 ListBox
的基本控件模板了,这我们在第一部分中简要介绍过。我们将先学习控件模板,然后在下一篇教程中学习内容布局和生成的项模板。请理解这是一个面向设计者的教程,因此我可能会简化一些内容,以便让初学者更容易理解Blend(我不想吓跑任何有潜力的设计师!)。本教程的基础是 Defwebserver 的 MVVM 文件管理器,我计划为他进行样式设置。
所以,请从此链接在 Blend 4 中打开 Defwebserver 的演示应用程序,我们就可以开始。
再次,在开始本教程之前,我建议您阅读我之前的 CodeProject 教程。
我正在将它们写成一个系列,因此本教程将假定您已具备先验知识。
- 第一课 - "构建更佳按钮"(入门指南)
- 第 2 课 - "街机按钮"(如何控制
Control Template
中元素的位置) - 第 3 课 - "画框控件"(什么是
Control
,以及为什么使用它?) - 第 4 课 - "最后 10 个按钮"(
WCDoor
按钮,以及所有 10 个可供下载的按钮) - 第 5 课 - "ListBox 样式 - 滚动条"(本教程的第一部分)
章节标题
- 第 1 章 - 安装滚动条
- 第 2 章 - 给它一个框架!
- 第 3 章 - 通用样式(应用程序/模块)
- 第 4 章 - ListBox 样式(终于!)
- 第 5 章 - 收尾工作
- 第 6 章 - 验证错误元素
- 第 7 章 - TreeView 样式(快速完成!)
- 第 8 章 - 新画框和最终调整
- 第九部分 - 来源
第 1 章 - 安装滚动条
恕我直言,Defwebserver 的这个效果不怎么样!但它目前还没有做任何事情……
(设计时使用的示例数据与运行时数据不同)。
我们想让它看起来更吸引人,同时也要与整个应用程序或网站的主题相匹配。
现在我们可以做的第一件事是,引入我们在第一部分中创建的 ScrollBars
。
在此处下载滚动条资源字典,并将其添加到您的项目中。
现在转到右侧的 ListBox
,编辑 Control Template
的副本,将其命名为“ListBoxStyleMVVM
”。
这现在应该会显示 ScrollViewer
,您同样需要为其创建 Control Template
的副本,并命名为“ScrollViewerStyleMVVM
”。
现在我们到了 ListBox
的 ScrollBars
,我们可以将 ScrollBar Style Resource
应用于垂直和水平滚动条。
但这并不会影响我们在设计时看到的 ScrollBars
,因为它们属于一个不同的 ScrollViewer
!
ListBox
本身位于一个 ScrollViewer
中,这是 Defwebserver 设置的,我也不想改变它。
(主要是因为它为后续格式化提供了便捷的控制,并帮助我们学习一些关于 Styles
的知识 - 所以感谢他!)。
因此,即使我们可能不使用这些 ScrollBars
,我绝对不希望出现不匹配的 ScrollBars
!
因此,为这些 ScrollBars
设置 Style
是明智之举!
现在选择 Template
中的 Rectangle
并将 Visibility
设置为 Collapsed
,因为我们不希望它出现在当前的 Style
中。
转到 ListBox
的父级 ScrollViewer
,并应用我们刚刚创建的 ScrollViewer Style Resource
。
(请注意,我们有嵌套项共享相同的 Style
,因此我们对一个所做的操作将应用于另一个)。
现在我们已经看到了样式化的滚动条。(只要您可以看到Sample Data
)。
选择 VerticalScrollBar
并查看 ScrollViewer
的这个组件的 Margins
。
这些设置对于 ScrollBars
的默认 Style
非常有效,但对于我们在第一部分中创建的 Style
则不然。
将左侧的 Margin
设置为 0
,其他所有侧面设置为 5
。
Artboard
中的任何内容都不会改变,因为 Vertical ScrollBar
不可见。
现在选择 Horizontal ScrollBar
,并将顶部 Margins
设置为 0
,其他所有侧面设置为 5
。
由于此 ScrollBar
可见,我们可以看到 Artboard
中的更新,如下所示
您在此处还可以看到左侧有一个 Grid divider
,这告诉我们上面的 ScrollContentPresenter
是为 ScrollBar
提供顶部 Margin
的项。
(ScrollContentPresenter
的 Margin
值绑定到 ScrollViewer Style
中的 Padding
。)
因此,我们看到示例数据和生成的内容在设计过程中有多么重要,因为我确实需要看到我所做的事情……在定位垂直和水平滚动条时,情况还不算太糟,但在其他情况下,设计和测试应用程序时拥有示例输入至关重要。
您可能也讨厌当前的红色 ScrollBar
,但此时我根本不在乎它的颜色。我只考虑 Layout
、Form
和 Contrast
。因此,我将以红色设计整个应用程序,不是因为我喜欢它。而是因为如果它在单调的红色中看起来不错,那么在最后选择实际颜色时它应该看起来很棒。所以请记住,这一切都是关于布局而不是颜色!
第 2 章 - 给它一个框架!
现在,我和 Defwebserver 对这个基本的文件夹导航器/管理器有更大的计划。但就目前而言,我将把它视为一个子窗口。因为它并不是一个完整的应用程序,更像是一个模块,可能构成一个应用程序。所以,考虑到这一点,我想在我们对 ListBox
本身进行样式设置之前,为整个东西添加一个边框或框架……这也是一个很好的机会来重用我在第三课中创建的资产,即画框控件。但首先,我们需要将父级 Grid
居中放置在为它设置的 Canvas
中。Canvas Layout
与 Grid Layout
不同,因为它使用从左上角开始的绝对坐标。因此,在使用 Canvas
时,您会看到略有不同的布局选项。如果您在做物理学和重力等事情,您必须使用 Canvas
,因为它是绝对坐标。
所以,选择 LayoutRoot Canvas
中的 Grid
,如下图所示
查看 Layout
属性,将 Width
设置为 500
,Height
设置为 300
,Left
设置为 50
,Top
设置为 50
。
这样应该可以将 TreeView
和 ListBox
居中放置在我们的 600x400 Canvas
中,如下图所示
(为清晰起见,我将我的 Canvas
设置为略微偏白的颜色)。
在此处下载PictureFramesControl Resource Dictionary
,并将其添加到您的项目中。
选择 Canvas LayoutRoot
元素,并在 Assets
菜单中找到 PictureFrameControl
。
将一个 PictureFrameControl
拖出以填充 Canvas
,使其 Width
和 Height
为 600x400
,Left
和 Top
都为 0
。
现在选择当前命名为“[ContentControl]
”的 PictureFrame
元素,并重置 Content
以删除 PictureFrame
中的文本。
请记住,PictureFrame
的类型是 ContentPresenter
,方括号表示它没有名称。(检查 XAML
。)
因此,将其重命名为“PictureFrame
”,在 XAML
中您可以看到,它现在有一个 x:Name=PictureFrame.
(而之前什么都没有)。
仍然选中 PictureFrame
,转到 Appearance
部分中的 BorderThickness
,并将所有值都设置为 50
。
这将使 PictureFrame
变粗,并使您的运行应用程序看起来像下图
(请记住,设计数据和运行时数据是不同的)。
现在我们有了要样式设置的 Controls
的周长,我建议最好在代表您的应用程序样式的内容中工作。
PictureFrameControl
非常灵活,因为我所做的来创建框架轮廓/形状,只是编辑了 Gradient Resources
。
框架几乎可以是任何东西,我将在后面的完成应用程序中提供一个不同的轮廓/样式,但这暂时就可以了。
(只需编辑Alpha值和颜色选择器进行尝试……您也可以这样做,因为我稍后会提供一个不同的!)。
第 3 章 - 通用样式(应用程序/模块)
最终,我们将进行 ListBox
的样式设置,但在此之前,我想谈谈透明度,以及这是否是个好主意?您可能希望背景图像能够透过您的 ListBox
和 Data
,但这会存在数据可读性的风险。如果背景加载失败,又会怎样?我不是要制造恐慌,但需要考虑!背景可能失败的最可能原因是在显示图像时。所以,合乎逻辑的做法是确保该图像视口的背景设置为适合您 Data/Content
的颜色。因此,即使我可能依靠更大的应用程序来提供此模块的背景颜色,我也会将 Canvas
设置为我们的背景颜色。如果此模块是子窗口,我毫不犹豫地设置背景颜色,因此决定已做出!我在这里使用背景的另一个原因是,可以确切地看到 ListBox Control
的各种 Templates
中填充属性的位置。为了最好地展示这一点,我将设置一个渐变!
选择 Canvas
元素并设置一个渐变填充,如下图所示
(使用颜色拾取器匹配画框的色调,但您可以选择自己喜欢的)。
将此保存为资源以备后用……
这应该会在运行时应用程序中为您提供一个背景填充,就像下图一样
(我将 GridSplitter
移到一边以显示 ListBox
的水平滚动条)
现在 GridSplitter
与此应用程序/模块的样式完全不匹配,无论是其形式还是颜色。
所以,这里有一个GridSplitter Resource Dictionary
,其中包含一个合适的样式。添加到项目中并将其应用到您的 GridSplitter
。
这个 GridSplitter Style
可能不是最终版本,但我希望您能看到只需插入 Styles 即可进行改进或调整是多么容易。
现在,当运行应用程序时,您的应用程序/模块应该看起来像下图
事物开始变得更加一致,GridSplitter
不再碍眼,所以我想我们可以最后看看 ListBox
了。
请忽略左侧的 TreeView
! :-)
第 4 章 - ListBox 样式(终于!)
现在看看上面部分中的 ListBox
(在右侧),我们有多个蓝色渐变边框。这是因为 ScrollViewer's Control Template
中有一个 Border
元素,它被模板绑定到 ScrollViewer Style
中的 BorderBrush
。现在我想将此 BorderBrush
设置为与应用程序其余部分的配色方案相匹配。因此,它会影响 ListBox
内的 ScrollViewer
的样式,以及 ListBox
外的 ScrollViewer
。现在,仅在根元素级别设置 ScrollViewer
的 BorderBrush
属性只会改变其本身的颜色,因此需要在 Style
中进行。或者您可能会这么想……但是,这两种方法都无法更改内部 ListBox
的 BorderBrush Border
颜色。原因在于 ListBox
正在覆盖这些 Style
指令,因为它连接到它的子 ScrollViewer
的父级!困惑吗?您会困惑的!:-) 但说真的,让我们开始吧,看看我们能做到什么……
选择 ListBox
的父级 ScrollViewer
,并在 Style
中重置 BorderBrush
。
(我们不想要这个 Border
,因为它会干扰 GridSplitter
)。
但请注意,它对内部 ScrollViewer
没有影响,这是因为 ListBox
覆盖了它,因为它是一个内部 ScrollViewer Control Part
的父级。
所以,选择 ListBox
,转到 Control Template
的 Style
,并将 BorderBrush
改为十六进制值:#FFC00000
的实心填充。
(看看这如何将 ListBox
的 Border
改为深红色,而不是其内部 ScrollViewer Control Part
的 BorderBrush
)。
现在,我希望白色的内部背景能够填充我们刚刚设置的红色 BorderBrush
。
为此,请转到 ListBox
中的 ScrollViewer
的 Style
,并将 Margins
从所有侧面的 5
改为 0
。
这应该会给您带来与下图相同的效果
但是我们遇到了一个问题!GridSplitter
失去了与 ListBox
的所有间距。
这是因为我们刚刚更改的 Style Margin
设置已应用于此 ScrollViewer
以及外部 ScrollViewer
(ListBox
所在的那个)。
因此,为了纠正这一点,并提供更好的 Layout
控制,我将撤消上一步(将 Margins
改回 5
)。
相反,我将复制这个 Control Template
,从而使其独立于 ListBox
的父级 ScrollViewer
。
(我们可以只为 GridSplitter
设置一个 Margin
,但新的 ScrollViewer Style
将提供更好的灵活性以供将来使用)。
所以,选择ListBox 控件模板内的ScrollViewer,然后选择Edit Template > Edit a Copy。
将新的 ScrollViewer Style
重命名为“ScrollViewerStyleListBoxMVVM
”,然后点击OK。
现在我们有了2个独立的 ScrollViewer Styles
,它们共享相同的 ScrollBar Style
。很有趣吧?
(当你搞懂了,其实也没那么糟。)
现在转到 ListBox ScrollViewer
的 Style
,并将此 Style
的 Margin
设置为所有侧面为 0
。
这应该只会改变ListBox 内 ScrollViewer
的边框边距,如下图所示
(上图显示的是设计时数据。)
现在 ListBox
内的 ScrollViewer
填充了整个 ListBox
。
(但没有改变 ListBox
外面的 ScrollViewer
,以及它与 GridSplitter
和 ScrollBar
的间距) - 正如预期的那样!
现在进入 ListBox
内的 ScrollViewer
的 Control Template
,并选择 Grid
元素。
查看 Grid
元素的背景/填充,并看到它是模板绑定到 Style
的背景颜色的。这个 Grid
提供了我们 ListBox
的背景颜色,我想要圆角。而 Grid
没有这个属性,我需要一个 Rectangle
或 Border
元素来完成…… Grid
位于一个 Border
元素内部,而 BorderBrush
被模板绑定到 Style
的 BorderBrush
。(我不知道为什么 Border
元素不同时控制填充/背景和描边/边框画笔)。
选择 Grid
并将背景重置为 No Brush
。
转到 Border
元素,选择 Background
属性,并将其模板绑定到 Style
。
现在将 Border
元素的 CornerRadius
改为 20
,如下图所示
您在这里还会看到,BorderThickness
被模板绑定到 Style
,并设置为 0
。
父级 ListBox
负责这一点,并删除了 ScrollViewer
显示其 BorderBrush
的能力,因为 ListBox
希望自己处理这一点,这也是我们之前无法更改此控件部分的 Border
颜色的原因。
但回到 CornerRadius
,Artboard
中的 ListBox
应该看起来像下图
现在我应用了过多的 CornerRadius
,这突显了 CornerRadius
可能出现的问题。看看页面图标(page_white.png)实际上已经超出了白色背景的半径角。我们可以重新格式化内容来解决这个问题,并考虑到 CornerRadius
,但这会浪费“空间”,而且工作量很大!
所以我建议不要过度使用 CornerRadius
,并认为值为 6
对于我们正在创建的 Style
就足够了。
接下来转到 ListBox Control Template
,选择 Border
元素,并将 CornerRadius
改为 7
。
现在为了稍微整理一下,选择 ListBox
中的 ScrollViewer
,并将其 BorderBrush
模板绑定到 ListBox Style
。
(这不会有可见的效果,因为 ScrollViewer
和 Border
元素的 BorderThickness
都设置为 0
,正如我之前讨论过的)。
现在去 ListBox
的 Style
,设置您喜欢的任何背景颜色,我选择了一个轻微的红色渐变。
为了清晰起见,我们只有非常浅的背景或非常深的背景可供选择。因此,轻微的彩色提示渐变是我唯一可以依靠的,以安全地清晰地显示内容。但是,在 Style
中设置渐变比设置实心颜色更麻烦,尤其是在尝试不同的配色方案时……
所以将 ListBox
的背景颜色设置为亮红色,我们将在 ScrollViewer Control Template
中使用白色叠加层来提供渐变。
现在转到 ListBox
中 ScrollViewer
的 Control Template
,并选择 Border
元素内的 Grid
。
现在插入一个 Border
元素来填充 Grid
元素,将其设置为 Stretch
、Auto-Sized
和 0 Margins
。
接下来将 BorderThickness
模板绑定到 Style BorderThickness
,这将使其所有侧面都为 0
。
将背景颜色更改为线性渐变,将两者都设置为白色,并在色带的 40
和 60
处添加2个额外的渐变停止点。
将两个末尾的渐变停止点设置为 90% Alpha
,并将2个中间的渐变停止点保留为 100% Alpha
。
现在将新的 Border
元素重命名为“BGroundOverlay
”,将 CornerRadius
设置为 6
,将元素 Opacity
设置为 95%
。
最后,在 Objects and Timeline
中,将新的 Border
元素移动到 Grid
子元素的最顶部,如下图所示
这样,叠加层就位于 ScrollContentPresenter
之后,因此位于生成的内容之后。
并且,希望当应用程序运行时,您的 ListBox
会看起来像下图
您现在可以更改 ListBox
的实心背景颜色,并始终保留渐变!
(我不是说我的值是正确的,我只选择了我知道在本次教程中会显示的值)。
您可能会认为,ListBox
的基本样式设置已经完成,但我们犯了一个错误!
选择 ListBox
(不在 Control Template
中),然后打开 Layout
部分的扩展属性。
现在找到 HorizontalScrollBarVisibility
并将其设置为 Visible
。
(我将我的 Layout
部分向右拖动以显示完整的名称)。
这应该会改变 Artboard
中的 ListBox
,使其看起来像下图
除非我们想要 ListBox ScrollBar
区域有一个难看的红色背景,否则效果并不好。
问题在于,我们只设置了叠加层来覆盖它所在的 Grid
的一部分。
所以,进入 ListBox
,然后进入 ScrollViewer's Control Template
,并选择 Grid
元素。
查看下图左下角的行分隔线以及列分隔线。(右上角)
您会看到行分隔线现在已展开,因为 ScrollBar
已变为 Visible
以填充该 Grid
的细分。我们希望我们的叠加层覆盖这个区域,这样它才能正常工作!现在我们可以尝试告诉叠加层完全覆盖 Grid
的所有细分,但这总是让叠加层听任 Grid
的摆布。如果叠加层是 Grid
的父级会怎么样,这样它将始终适用于 Grid
中的所有内容。但 Border
元素只能有一个子元素(就像大多数控件一样),只有 Grid
可以有多个子元素。并且由于 Grid
目前是根边框元素的子级,我们需要叠加层成为根边框元素的子级,而 Grid
成为叠加层的子级。(基本上将叠加层插入边框和网格之间)。
很简单,只需在 Objects & Timeline
中选择 BGroundOverlay
元素,然后将其拖到根边框元素上。
这应该会改变父子关系,如下图所示
确保所有 Margins
都设置为 0
,并且 Width
和 Height
都设置为 Auto
。运行时应用程序应该看起来像下图
第 5 章 - 收尾工作
现在,我在本教程的早期为 ScrollBars
设置了一些 Margins
,它们现在已经不太合适了。因为看到的 2 个水平滚动条的底部,其底部的 Margin
比我想要的要大。在我们跳入更改 ScrollBars
甚至 ScrollBar Style
之前。我们需要记住,ScrollBar Style
同时适用于可见的 2 个水平滚动条。上面的那个在 ListBox
内部,因此没有被调用,但请注意,它很好地适应了 ListBox
的查看窗格。更改其中一个 ScrollBar
的样式会影响另一个 ScrollBar
。所以我可能会创建一个全新的样式,就像我为 ScrollViewer
所做的一样。(事实上,当时这有点多余,因为我本可以简单地覆盖控件根节点中的样式)。对于对少数 Controls
进行一些调整来说,这是可以的,但当需要对许多 Controls
进行大量调整时,这会非常耗时。因此,这实际上是关于权衡,以决定是否值得创建新的样式以及该样式中应定义什么。例如,此处使用的 ScrollBars
在样式中根本没有设置 Margins
,但在 ScrollViewer
中使用时具有 Margin
偏移量。因为我们在 ScrollViewer's Control Template
中为 ScrollBars
提供了偏移量。因此,当使用具有此样式的 ScrollViewer
时,ScrollBars
将自动接收 ScrollViewer's Control Template
的偏移量。希望这会让你觉得为 ScrollBar
应用 Margins
是个坏主意,因为你可能会在这里适配它,但在其他地方弄坏它。保持基本的核心块简单,并将调整添加到链条的最高层!
因此,请确保您不在任何控件模板中,选择 ListBox
并将 HorizontalScrollBarVisibility
改为 Auto
,使其消失。
现在选择 ListBox
的父级 ScrollViewer
,命名为“FileDetails
”,将左侧 Margin
保留为 5
,并将其他所有边都设置为 0
。
这将使 ScrollViewer
和子 ListBox
在所有侧面都能很好地放置在 PictureFrame
内部,如下图所示
(如果父级 ScrollViewer
的滚动条设置为 Hidden
,则包含的 ListBox
仍然可以很好地填充整个区域)。
请继续忽略左侧未设置样式的 TreeView
,但对于右侧的 ScrollViewer
和 ListBox
,其余部分取决于个人品味……
现在您可能会想,为什么我们需要2个不同的 ScrollViewer Styles
。一个用于 ListBox
的父级 ScrollViewer
,另一个用于 ListBox
的控件部分的 ScrollViewer
。正如我之前所说:这允许2个不同的 Margins
间距设置,但它也允许我们目前使用的2个不同的背景设置。还记得我们为 ListBox
内的 ScrollViewer
添加的 BGroundOverlay
元素吗?由于它是 ScrollViewer's Control Template
的一部分,因此它也是该样式的一部分。因此,如果我们将其样式应用于 ListBox
的父级 ScrollViewer
,它也会有这个 BGroundOverlay
元素。而且由于我们没有可以轻松模板绑定到此元素背景/填充属性的属性,因此我们无法轻松地将其打开或关闭。所以,确实,我们需要这个应用程序中的 ScrollViewer
的2个样式。
第 6 章 - 验证错误元素
在 ListBox Control Template
中,除了 ScrollViewer
,您还应该有一个类型为 Border
的 ValidationErrorElement
。
在此 Border
内有一个 Grid
,用于容纳 2 个 Path
元素,用于指示验证错误。这很可能只由开发人员实现,但设计师需要考虑这些元素,即使他们在设计时不太可能看到它们。那么,我们如何才能在设计时看到这些通常不可见的元素,并且处于未定义关键帧的状态呢?
转到States Manager (VSM),在Base State中,点击几乎看不见的黑色圆圈以弹出眼睛图标。
现在我们可以模拟InvalidFocused State,并看到如果开发人员的代码输入规则未被遵守,用户将看到什么。
(Unfocused 和 Focused States 通常是相同的,但可能不同)。
为这个State组添加持续时间也没有意义,据我所知,ValidationErrorElements
的显示方式不会随时间动画。
(这是因为 Border
元素从Collapsed State变为Visible State,而不是改变元素的Opacity)。
选中 ValidationErrorElement Border
元素后,转到 Artboard
,使用Selection工具,将右边缘拖入视图,如下图所示
(或者只需将右侧的Margin设置为大约 125
)。
这样应该会显示所有ValidationErrorElements,在右上方显示一个红色边框和2 个 Path 元素。
仍选中 Border ValidationErrorElement
,将 CornerRadius
改为 7
,以匹配我们新的样式。
现在看看边框右上角的2 个 Path 元素,如下图所示。
这些Vector Path 元素的设计是针对CornerRadius为 2
的,几乎所有默认控件也是如此。所以,如果您想更改这一点,则需要在您样式设置的每个控件中进行更改,以匹配此控件。改变颜色也是如此……所以为了暂时保持简单,我将保持原样。因为它们仍然应该适合我们当前的样式。(希望如此!)
所以,将ValidationErrorElement的Margins重置,这就是我们需要在这里做的全部。我知道红色在我们的红色应用程序中并不显眼,但谁说这个应用程序必须是红色的?即使介绍图片显示的是红色应用程序……
这样就完成了 ListBox
的控件模板的样式设置!
第 7 章 - TreeView 样式(快速完成!)
这实际上不是教程的一部分,但 TreeView
需要一些工作,才能与 ListBox
保持一致。而且由于我们已经创建了样式,这会相当简单。所以,请确保您不在任何模板中,将 PictureFrame
拖到 Grid
后面以将其移开,然后我们可以开始。
选择名为“FileFolders
”的 ScrollViewer
,右键单击并选择 Edit Template > Apply Resource > ScrollViewerStyleMVVM
,如下图所示
现在将右侧的Margins设置为 5
,其他 3 侧设置为 0
,如下图所示
现在展开名为“FileFolders
”的 ScrollViewer
,并选择子 TreeView Control
。
接下来选择控件模板的Edit a Copy,将其命名为“TreeViewStyleMVVM
”,然后点击OK。
转到 TreeView
的 Style
,将背景设置为亮红色,将边框画笔设置为深红色。
(使用Artboard上的颜色选择器进行颜色匹配)。
现在在控件模板中,选择 ScrollViewer
,右键单击并选择Edit Template >Apply Resource >ScrollViewerStyleListBoxMVVM。
这显然应用了与 ListBox
中的 ScrollViewer
相同的 ScrollViewer Style
。因此,这个最初为 ListBox
创建的样式也适用于 TreeView
的 ScrollViewer
部分。这是因为它们基本上是相同的,都是构成更复杂控件的简单构建块。所有的动作(可以说是)都发生在样式模板的 ScrollContentPresenter
部分,而这由附加模板控制,我们将在下一篇文章中讨论。我们真正要做的这个 ScrollViewer
的控件模板中,就是布置舞台或构建内容。而且,因为我们希望 TreeView Style
与 ListBox Style
匹配,所以能够重用您的基本样式是有道理的!这意味着我将样式命名为“ScrollViewerStyleListBoxMVVM
”有点短视,因为我们将其用于 ListBox
以外的地方,所以将其更改为“ScrollViewerInnerMVVM
”。
要更改样式资源的名称,请转到Resources选项卡,然后双击(缓慢地)名称,以获得与下图相同的效果
将名称更改为“ScrollViewerInnerMVVM
”,然后按 Enter
。
应该会弹出一个窗口,询问如何处理名称引用,如下图所示
默认的“Update references
”就是我们想要的,所以点击Continue。
如果一切顺利,名称已更新,并且没有任何问题。
对名为“ScrollViewerStyleMVVM
”的 ScrollViewer Style
做同样的事情,将其更改为“ScrollViewerOuterMVVM
”。
回到 TreeView
的样式设置,并确保您处于 TreeView
的控件模板中(而不是 ScrollViewer
)。
选择最根部的 Border
元素,如下图所示,并将 CornerRadius
改为 7
。
现在选择子 Border
元素,将其 CornerRadius
设置为 6
,然后将所有侧面的Margins重置为 0
。
现在要删除由 Padding
应用的间距,请转到 TreeView
的 Style
,并将那里的 Padding
改为所有侧面为 0
。
这样,TreeView
现在应该与 ListBox
匹配,如下图所示
现在唯一需要整理的是 GridSplitter
,它是由 Defwebserver
随意添加到此演示应用程序中的。
所以,退出任何模板,选择 GridSplitter
并将 Width
改为 10
。
现在转到 Margins
并将左侧设置为 -5
,右侧无关紧要,因为我们是“左对齐”,所以保留为 0
。
将顶部和底部 Margins
都设置为 80
,或您喜欢的任何其他值……
但是您应该认识到,GridSplitter
始终是 10
像素宽,但其高度与表单相同,减去顶部和底部的Margin。不为 GridSplitter
设置固定高度可以为您的应用程序提供更好的灵活性,但仅限于一定范围。因为顶部和底部的Margin为 80
时,如果父项的高度低于 160
,则根本不会显示 GridSplitter
!因此,如果您只想要一个短的 GridSplitter
,最好设置一个固定的高度。您总是可以尝试结合使用 Y 轴的Scale transform,但这会使视觉元素变形(压扁)。尤其是像我们这里的圆角。所以,我将把我的顶部和底部Margin保留在 80,并假设这没问题……
第 8 章 - 新画框和最终调整
我承诺会提供一个新的 PictureFrame
,以防您弄坏了当前的。但即使我不提供更新的 PictureFrame
,也不是什么严重问题。因为您只需再次加载旧的即可重置渐变以及您可能做的任何其他更改……但我会提供一个新的 PictureFrame
,但想再次确保您的 PictureFrame
位于 Grid
后面,并且是 LayoutRoot Canvas
的第一个子元素,如下图所示
首先,将我们为 LayoutRoot
设置的背景复制到 Grid
中,并根据需要进行编辑。
在此处下载新的 Picture Frames Update (here),并将其添加到您的项目中。
如果一切按计划进行,您的项目应该看起来像下图
铆钉的颜色可以通过画框的背景颜色来更改,但这也会改变画框的内部背景,因此我们需要确保通过将我们想要的背景从 LayoutRoot Canvas
移到 Grid
来覆盖它。
这就是今天的全部内容!-所以请投票!!!
第九部分 - 来源
通过完成教程,您将始终学到更多知识,但这里是完整的项目供您玩!