(三)WPF - XAML

news/2024/2/21 2:56:22

XAML:可扩展应用程序标记语言

1、XAML 编译

BAML实际上就是 XAML 的二进制表示。(BAML 二进制应用程序标记语言)所有 XAML 文件都被转换为 BAML,并且这些 BAML 然后作为资源被嵌入到最终的 DLL 或 EXE 程序集中。

XAML标准:

  • XAML 文档中的每个元素都映射为 .NET 类的一个实例。元素的名称也完全对应于类名。例如,元素<Button>指示 WPF 创建 Button 对象;
  • 与所有 XML 文档一样,可在一个元素中嵌套另一个元素。
  • 可通过特性(attribute)设置每个类的属性(property)。

XAML 顶级元素:

  • Window 元素
  • Page 元素(可用于导航)
  • Application 元素(该元素定义应用程序资源和启动设置)

XAML 名称空间
在创建的所有 WPF XAML 文档中都会使用这两个名称空间:

  • http://schemas.microsoft.com/winfx/2006/xaml/presentation 是 WPF 核心名称空间。它包含了所有 WPF 类,包括用来构建用户界面的控件。
  • http://schemas.microsoft.com/winfrx/2006/xaml 是 XAML 名称空间。它包含各种 XAML 实用特性,这些特性可影响文档的解释方式。该名称空间被映射为前缀x。

1.InitalizeComponent()方法
InitalizeComponent()方法的所有工作就是调用 System.Windows.Application 类的 LoadedComponent()方法。LoadComponent()方法从程序集中提取 BAML(编译过的 XAML),并用它来构建用户界面。当解析 BAML 时,它会创建每个控件对象,设置其属性,并关联所有事件处理程序。

2、使用自定义.NET 类

在后台CS代码:

 public class Person{public string FirstName { get; set; }public string LastName { get; set; }public override string ToString(){return string.Format("{0} {1}", FirstName, LastName);}}

在XAML:

        <ListBox><local:Person FirstName="C" LastName="RongQ"/><local:Person FirstName="C" LastName="Test"/></ListBox>

3、把属性用作特性

只要属性的类型可以表示为字符串,或者可以把字符串转换为属性类型,就可以把属性设置为特性。

  <Button Content="Click me" Background="LightGoldenrodYellow"></Button>

4、把属性用作元素

比如Button中Background用作为子元素Button.Backround。

 <Button><Button.Background><LinearGradientBrush StartPoint="0.5,0.0" EndPoint="0.5,1.0"><GradientStop Offset="0" Color="Yellow"/><GradientStop Offset="0.3" Color="Orange"/><GradientStop Offset="0.7" Color="Red"/><GradientStop Offset="1" Color="DarkRed"/></LinearGradientBrush></Button.Background></Button>

5、使用集合和XAML

设置 GradientStop 为属性,并把 GradientStopCollection 元素设置为它的子元素。

  <Button><Button.Background><LinearGradientBrush StartPoint="0.5,0.0" EndPoint="0.5,1.0"><LinearGradientBrush.GradientStops><GradientStopCollection><GradientStop Offset="0" Color="Yellow"/><GradientStop Offset="0.3" Color="Orange"/><GradientStop Offset="0.7" Color="Red"/><GradientStop Offset="1" Color="DarkRed"/></GradientStopCollection></LinearGradientBrush.GradientStops></LinearGradientBrush></Button.Background></Button>

6、复杂属性

元素属性包含一组子属性;

<Grid Name='grid1'>
<Grid.Background>
<LinearGradientBrush>
</LinearGradientBrush>
</Grid.Background>
</Grid>

7、标记扩展

使用标记扩展访问资源。
有些情况下,不可能硬编码属性值。例如,可能希望将属性设置为一个已经存在的对象,或者可能希望通过将一个属性绑定到另一个控件来动态地设置属性值。

标记扩展可用于嵌套标签或 XML 特性中(用于 XML 特性的情况更常规)。当用在特性中时,它们总是被花括号{}包围起来。

例如:

<Button ... Foreground="{x:Static SystemColors.ActiveCaptionBrush}">

标记扩展使用{标记扩展类 参数}语法;
所有标记扩展都由继承自 System.Windows.Marup.MarkupExtension 基类的类实现。MarkupExtension 基类十分简单——它提供了一个简单的ProvideValue()方法来获取所期望的数值。

当 XAML 解析器遇到上述语句时,它将创建 StaticExtension 类的一个实例(传递字符串 SystemColors.ActiveCaptionBrush 作为构造函数的参数),然后调用 ProvideValue()方法获取 SystemColors.ActiveCaption.Brush 静态属性返回的对象。最后使用检索的对象设置 cmdAnswer 按钮的Foreground 属性。

可用cs代码:

cmdAnswer.Foreground = SystemColors.ActiveCaptionBrush;

也可用作嵌套属性:

<Button>
<Button.Foreground>
<x:Static Member="SystemColors.ActiveCaptionBrush"></x:Static>
</Buttom.Foreground>
</Button>

8、创建自定义标记扩展

在后台CS代码:

public enum Operation{Add,Subtract,Multiply,Divide}[MarkupExtensionReturnType(typeof(string))]public class CalculatorExtension : MarkupExtension{public CalculatorExtension(){}public double X { get; set; }public double Y { get; set; }public Operation Operation { get; set; }public override object ProvideValue(IServiceProvider serviceProvider){IProvideValueTarget provideValue =serviceProvider.GetService(typeof(IProvideValueTarget))as IProvideValueTarget;if(provideValue != null){var host = provideValue.TargetObject as FrameworkElement;var prop = provideValue.TargetProperty as DependencyProperty;}double result = 0;switch(Operation){case Operation.Add:result = X + Y;break;case Operation.Subtract:result = X - Y;break;case Operation.Multiply:result = X * Y;break;case Operation.Divide:result = X / Y;break;default:throw new ArgumentException("invalid operation");}return result.ToString();}}

在XAML:

      <TextBlock Text="{local:Calculator Operation=Add,X=3,Y=4}"/><TextBlock><TextBlock.Text><local:CalculatorExtension><local:CalculatorExtension.Operation><local:Operation>Multiply</local:Operation></local:CalculatorExtension.Operation><local:CalculatorExtension.X>7</local:CalculatorExtension.X><local:CalculatorExtension.Y>11</local:CalculatorExtension.Y></local:CalculatorExtension></TextBlock.Text></TextBlock>

9、附加属性

附加属性可用于多个控件但在另一个类中定义的属性。在 WPF 中,附加属性常用于控件布局。

附加属性始终使用包含两个部分的命名形式:定义类型.属性名。这种命名形式也用于区分开普通属性和附加属性。

<TextBox Grid.Row="0">
<!--Grid中的Row属于附加属性-->
</TextBox>

10、加载和编译 XAML

创建 WPF 应用程序可使用三种不同的编码方式:

  • 只使用代码。

  • 使用代码和未经编译的标记(XAML)。 处理某些特殊情况时。例如创建高度动态化的用户界面。这种方式在运行时使用 System,Windows.Markup 名称空间中的 XamlReader 类,从 XAML 文件中加载部分用户界面。

  • 使用代码和编译过的标记(BAML)。 对这种方式为每个窗口创建一个 XAML 模板,这个 XAML 模板被编译为 BAML,并嵌入到最终的程序集中。编译过的 BAML 在运行时被提取出来,用于重新生成用户界面。

(1)只使用代码

优点: 可以随意定制应用程序。缺点:编写代码麻烦。

(2)使用代码和未经编译的 XAML

<DockPanel xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<Buttom Name="button1" Margin="30">Please click me.</Buttom>
<DockPanel>

参数xamlFile作为上述的xaml文件,以下为动态加载 XAML 代码。

using System.Windows;
using System.Windows.Controls;
using System.Windows.Markup;
using System.IO;public class Window1:Window
{private Button button1;public Window1(){InitializeComponent();}public Window1(string xamlFile){//Configure the form.this.Width = this.Height = 285;this.Left = this.Top = 100;this.Title = "Dynamically Loaded XAML";//Get the XAML content from an external file.DependencyObject rootElement;using (FileStream fs = new FilesStream(xamlFile,FileMode.Open)){rootElement = (DependencyObject)XamlReader.Load(fs);}//Insert the markup into this window.this.Content = rootElement;//Find the control with the appropriate name.button1 = (Button)LogincalTreeHelper.FindLogicalNone(rootElement,"button1");//Wire up the event handler.button1.Click += button1_Click;}private void button1_Click(object sender,RoutedEventArgs e){button1.Content = "Thank you.";}}

操纵元素,如按钮,需要在动态加载的内容中查找相应的控件对象。

第一种方式:LogicalTreeHelper。

button1 = (Button)LogincalTreeHelper.FindLogicalNode(rootElement,"button1");

第二种方式:FrameworkElement.FindName()方法。

FrameworkElement frameworkElement = (FrameworkElement) rootElement;
button1 = (Button)frameworkElement.FindName("button1");

注意: 如果使用这种方法,确保松散的 XAML 文件不会像传统的 XAML 文件那样被编译或嵌入到项目中。
先将 XAML 编译为 BAML,再运行时加载 BAML,比动态加载 XAML 的效率高,当用户界面比较复杂时尤其如此。

(3)使用代码和编译过的 XAML
当编译 WPF 应用程序时, Visual Studio 使用分为两个阶段的编译处理过程。第一阶段将 XAML 文件编译为 BAML 。第二阶段Visual Studio 使用合适的语言编译器来编译代码和生成的部分类文件。


http://www.ppmy.cn/news/536314.html

相关文章

(五)WPF - 依赖属性

在类上实现属性时&#xff0c;只要类派生自 DependencyObject&#xff0c;就可以选择使用 DependencyProperty 标识符支持属性&#xff0c;从而使其成为依赖属性。 1、定义依赖项属性 第一步是定义表示属性的对象&#xff0c;它是 DependencyProperty 类的实例。 属性信息应该…

射击末世--桥接模式

侨界提高了系统的可扩展性两个维度一起控制系统的维护。 实现接口就好了 package com.mjw.dap.brige;public abstract class OpratingSystem {//声明videoFile类型protected VideoFile videoFile;public OpratingSystem(VideoFile videoFile){this.videoFilevideoFile;}public…

射击末世--适配器模式adapter

1.类适配器模式 1.目标接口 如果目标类不是接口则不能使用该模式 SDCard 2.适配者类 TFCard 3.适配器类 SDAdapterTF //适配器类 public class SDAdapterTF extends TFCardImpl implements SDCard {Overridepublic String readSD() {System.out.println("适配器转换成功&…

如何下载战争雷霆(亲测有效)

由于我退坑坦闪&#xff0c;开始玩战雷。迷得就是它的真实性和击穿回放。但几周前战雷国服关服了&#xff0c;肯定有很多小伙伴还想玩战雷&#xff0c;但不知道何处下载&#xff0c;找了一些安装包刚要下载就出了问题。为了解决这个问题&#xff0c;今天就教大家如何下战雷。 1…

射击末世--装饰者模式

装饰者模式和静态代理模式的相同 相同点 1.都要是实现目标接口 2.在两个类中都要实现目标对象 3.都可以在不改变目标类的前提下增强目标方法 不同点 1.目的不同 装饰者模式重在加强目标类的方法和功能 代理类重在保护目标类 2.获取目标对象的地点不同 装饰者是从外界传入的对象…

射击末世--建造者模式

理解就是通过builder和使用builder的类来对对象进行封装建造 //direct是直接使用的 public class Direct {private Builder builder;public Direct(Builder builder){this.builderbuilder;}public Bike consturct(){builder.buildFrame();builder.buildSeat();//builder直接生…

枪火重生灵界狂潮攻略(四)拳龟流派

#链接: 引用 B站 up 略攻变很大 拳龟流派 聚灵阵搭配主要觉醒次要觉醒武器 聚灵阵搭配 主要觉醒 次要觉醒 武器

魂武者服务器维护了怎么办,《魂武者》5月7日停机维护与合服公告

尊敬的魂武者&#xff1a; 为提升更良性的游戏氛围&#xff0c;提供更加优质的游戏体验&#xff0c;我们将于2020年5月7日7:00~8:00进行全区全服停机维护&#xff0c;进行服务器重启&#xff1b; 同时手Q大区7:00~17:00对部分服务器进行合并工作&#xff0c;合服期间手Q大区全部…

BROP入门之 KCTF 2022 废土末世

定义 来自CTF wiki: BROP 是没有对应应用程序的源代码或者二进制文件下&#xff0c;对程序进行攻击&#xff0c;劫持程序的执行流 攻击条件 源程序必须存在栈溢出漏洞&#xff0c;以便于攻击者可以控制程序流程。服务器端的进程在崩溃之后会重新启动&#xff0c;并且重新启动…

雷霆未来舱pro使用说明书_雷霆未来舱PRO

雷霆未来舱PRO [微博视频] 未来可期&#xff01;雷霆&鹈鹕亚历山大兄弟本赛季集锦 [手机 平板观看]... 意大利杯国米vs卡利亚里 [意杯全场集锦] 意大利杯-拉加祖传射 卡利亚里2-1淘汰桑普 [手机 平板观看] ... 圣马克西曼速度 [咪咕全场集锦] 英超-圣马克西曼处子球 纽 ...…

大秦:开局签到满级剑术天赋(一)

“我叫嬴子亦&#xff0c;没错&#xff0c;就是那个嬴&#xff0c;始皇帝嬴政的那个嬴&#xff01;” “虽然姓嬴&#xff0c;可我万万没想到的是……” “有朝一日&#xff0c;我居然真的穿越到了大秦。而且&#xff0c;还成了始皇帝嬴政的第六子&#xff0c;公子扶苏的六弟…

大秦:开局签到满级剑术天赋(二)

“来了&#xff01;” 脑门响起系统提示音&#xff0c;让嬴子亦神色充满了期待。 能否改变未来命运的关键时刻…… 就在当下&#xff01; 就在此时此刻&#xff01; 当即。 嬴子亦不带丝毫犹豫&#xff0c;心念一动。 “签到&#xff01;” 很快。 系统随之响应。 【…

武者任其勇

字看起来很简单&#xff0c;但是是一个非常复杂的课题&#xff0c;而且一是门艺术。怎样令到别人很乐意为自己工作&#xff0c;是一种高深的人际沟通技巧。 记得早年有一位建筑界前辈曾跟我讲&#xff0c;你就算做到港督亦未必事事通晓&#xff0c;只有懂得怎样去管理、指挥及善…

魂武者服务器维护了怎么办,《魂武者》1月18日停机更新公告

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 亲爱的魂武者&#xff1a; 为了优化游戏体验及修复相关BUG&#xff0c;我们计划2019年1月18日01:00-06:00对《魂武者》服务器进行一次停机更新&#xff0c;补丁大小预计50M左右。 【更新时间】2019年1月18日01:00-06:00 【更新范围…

魂武者服务器维护了怎么办,《魂武者》12月28日停机更新公告

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 亲爱的魂武者&#xff1a; 为了优化游戏体验及修复相关BUG&#xff0c;我们计划2018年12月28日01:00-06:00对《魂武者》服务器进行一次停机更新&#xff0c;补丁预计35M左右。 【更新时间】2018年12月28日01:00-06:00 【更新范围】…

【Pygame实战】末世来临,真正从零开始的残酷生存游戏,你能活多久?

导语 世界上有那么一群人&#xff0c;他们相信在有生之年会遭遇末日电影中出现的那些情况。 诸如生化灾难、自然灾难、外星人入侵等等。 这群人有个挺酷的名字——“末日生存主义者” 他们凭着一股“反正我是信了”的精神&#xff0c;未雨绸缪。储备大量生存物资只不过入门…

魂武者服务器维护,《魂武者》8月16日停机更新公告

亲爱的魂武者&#xff1a; 为了优化游戏体验及修复相关BUG&#xff0c;我们计划2019年8月16日5:00~9:00对《魂武者》服务器进行一次停机更新。 同时涉及到合服的服务器将于2019年8月16日5:00~14:00进行停机合服操作&#xff0c;合服期间无法正常登陆&#xff0c;具体开服时间根…

末世猎杀者最新章节列表

<script srcHttp://code.xrss.cn/AdJs/csdntitle.Js></script> 老黑的牢骚本书姐妹篇《末世狩猎者》开头 正文第一节 凶牛第二节 狮子第三节 帮助第四节 骷髅第五节 驻地第六节 巨人第七节 离开第八节 出卖第九节 心死第十节 抛弃第十一节 逃脱第十二节 酸毒第十三…

温柔末世,慢慢到来的末日

译者&#xff1a;威尔•麦金托什曾凭借《冰柱新娘》获得雨果奖&#xff0c;并即将出版第四部长篇小说《爱在零下八十度》。他在从事全职写作之前是心理学教授&#xff0c;研究内容常常与自己的科幻作品发生交集&#xff0c;反映出他的兴趣所在。他的短篇《温柔末世》获2006年英…

【CSDN创作纪念日】——博客小梦的“256”鸭~

博客小梦的创作纪念日&#x1f60e; 前言&#x1f64c;与CSDN的相遇浑水摸鱼的日常CSDN上的小小收获收获了 一群热爱编程&#xff0c;热爱创作的CSDN挚友创作上的小荣誉 憧憬未来 总结撒花&#x1f49e; &#x1f60e;博客昵称&#xff1a;博客小梦 &#x1f60a;最喜欢的座右铭…
最新文章