WPF 教程(wpf架构)

WPF介绍了一个非常方便的概念:把数据储存为一种资源,无论是本地控件、本地窗口还是全局应用。数据可以是任何你想要的东西,从实际的信息到WPF控件的层次结构都行。这非常有用,你可以把数据放在一个地方,然后在其他地方调用它。这个概念被广泛用在样式和模版,我们后面会详细讲到。也可以用在很多别的地方,就像本章要说明的地方,例子如下:

大家好,又见面了,我是你们的朋友全栈君。

WPF介绍了一个非常方便的概念:把数据储存为一种资源,无论是本地控件、本地窗口还是全局应用。数据可以是任何你想要的东西,从实际的信息到WPF控件的层次结构都行。这非常有用,你可以把数据放在一个地方,然后在其他地方调用它。

这个概念被广泛用在样式和模版,我们后面会详细讲到。也可以用在很多别的地方,就像本章要说明的地方,例子如下:

<span style="font-size:14px;"><Window x:Class="WpfTutorialSamples.WPF_Application.ResourceSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        Title="ResourceSample" Height="150" Width="350">
    <Window.Resources>
        <sys:String x:Key="strHelloWorld">Hello, world!</sys:String>
    </Window.Resources>
    <StackPanel Margin="10">
        <TextBlock Text="{StaticResource strHelloWorld}" FontSize="56" />
        <TextBlock>Just another "<TextBlock Text="{StaticResource strHelloWorld}" />" example, but with resources!</TextBlock>
    </StackPanel>
</Window></span>

WPF 教程(wpf架构)

资源使用x:Key属性来定义一个关键字,使用该关键字,就可以从应用的其他地方来引用了。你需要用到StaticResource这个标记扩展符。在上面的例子中,我定义了一个简单的字符串(Hello,world!),然后在两个不同的文本块里面进行引用。

StaticResource与DynamicResource

上面的例子我用了StaticResource这个标记扩展符来引用资源,其实还有另外一种形式:DynamicResource(动态资源)。
两者主要的区别是,静态资源只在XAML加载的时候引用一次。如果这个资源后面被修改了,并不会在前面引用的地方生效。动态资源正好相反,在需要时才引用,因此所做的更改都会影响到引用的地方。打个比方,一个是绑定到一个静态值,一个是绑定一个函数,这个函数监视值,每当值发生变化的时候发送给你。尽管严格意义上来讲不是这样的,但你可以这么理解,也就明白了什么时候用,用哪一种。动态资源也可以只在运行时使用,譬如在应用启动的时候从后台代码添加进来。

其他资源类型
共享一个简单的字符串其实是很容易的,然而,你可以做的更多。下面的例子,我将存储一个字符串数组,以及一个用于背景的渐变画笔。这应该让你明白你能用资源做很多事情。

<span style="font-size:14px;"><Window x:Class="WpfTutorialSamples.WPF_Application.ExtendedResourceSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        Title="ExtendedResourceSample" Height="160" Width="300"
        Background="{DynamicResource WindowBackgroundBrush}">
    <Window.Resources>
        <sys:String x:Key="ComboBoxTitle">Items:</sys:String>

        <x:Array x:Key="ComboBoxItems" Type="sys:String">
            <sys:String>Item #1</sys:String>
            <sys:String>Item #2</sys:String>
            <sys:String>Item #3</sys:String>
        </x:Array>

        <LinearGradientBrush x:Key="WindowBackgroundBrush">
            <GradientStop Offset="0" Color="Silver"/>
            <GradientStop Offset="1" Color="Gray"/>
        </LinearGradientBrush>
    </Window.Resources>
    <StackPanel Margin="10">
        <Label Content="{StaticResource ComboBoxTitle}" />
        <ComboBox ItemsSource="{StaticResource ComboBoxItems}" />
    </StackPanel>
</Window></span>

这次我们添加了一组额外的资源,窗体包含了一个简单的字符串,一个字符串数组和一个渐变画刷。字符串用于标签,数组用于下拉组合框,画刷用于整个窗口的背景。就像这样很多东西都可被存为资源。


本地资源和应用范围的资源

目前为止我们都是在窗口层存储资源,也就意味着你可以在整个窗口访问这些资源。
如果你只是想把资源用于具体的某个控件,你可以直接添加到控件里面,而不用在窗口层添加,这样更显本地化。工作情况一模一样,唯一的区别是你只能在这个控件范围内访问资源。
<span style="font-size:14px;"><StackPanel Margin="10">    <StackPanel.Resources>        <sys:String x:Key="ComboBoxTitle">Items:</sys:String>    </StackPanel.Resources>    <Label Content="{StaticResource ComboBoxTitle}" /></StackPanel></span>

上面的例子中,我们把资源添加到StackPanel控件里面,并用到子控件Label。只要是在StackPanel里的子控件都可以使用这个资源,而在StackPanel外面的控件则无法使用这个资源。

如果你想在几个窗口之间访问资源,也是可以做到的。App.xaml包含了像窗口或者其他WPF控件那样的资源,如果你把这些资源放到App.xaml中,那么这些资源就能被全局访问了。工作情况和窗口中的一样。
<span style="font-size:14px;"><Application x:Class="WpfTutorialSamples.App"             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"             xmlns:sys="clr-namespace:System;assembly=mscorlib"             StartupUri="WPF application/ExtendedResourceSample.xaml">    <Application.Resources>        <sys:String x:Key="ComboBoxTitle">Items:</sys:String>    </Application.Resources></Application></span>


WPF自动逐级向上搜索,从本地控件到整个窗口,再到App.xaml,来找到这个资源。

<span style="font-size:14px;"><Label Content="{StaticResource ComboBoxTitle}" /></span>

后台代码的资源


我们通过一个标记扩展,访问了XAML的所有资源。同样的,你也可以从后台代码访问各种资源,在某些场景下非常有用。前面的例子我们把资源放在不同的地方,因此接下来的例子,我们将资源放在在三个不同的范畴,然后在后台代码访问它们。

App.xaml:
<span style="font-size:14px;"><Application x:Class="WpfTutorialSamples.App"             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"             xmlns:sys="clr-namespace:System;assembly=mscorlib"             StartupUri="WPF application/ResourcesFromCodeBehindSample.xaml">    <Application.Resources>        <sys:String x:Key="strApp">Hello, Application world!</sys:String>    </Application.Resources></Application></span>

Window:

<span style="font-size:14px;"><Window x:Class="WpfTutorialSamples.WPF_Application.ResourcesFromCodeBehindSample"        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"        xmlns:sys="clr-namespace:System;assembly=mscorlib"        Title="ResourcesFromCodeBehindSample" Height="175" Width="250">    <Window.Resources>        <sys:String x:Key="strWindow">Hello, Window world!</sys:String>    </Window.Resources>    <DockPanel Margin="10" Name="pnlMain">        <DockPanel.Resources>            <sys:String x:Key="strPanel">Hello, Panel world!</sys:String>        </DockPanel.Resources>        <WrapPanel DockPanel.Dock="Top" HorizontalAlignment="Center" Margin="10">            <Button Name="btnClickMe" Click="btnClickMe_Click">Click me!</Button>        </WrapPanel>        <ListBox Name="lbResult" />    </DockPanel></Window></span>

Code-behind:

<span style="font-size:14px;">using System;using System.Windows;namespace WpfTutorialSamples.WPF_Application{        public partial class ResourcesFromCodeBehindSample : Window        {                public ResourcesFromCodeBehindSample()                {                        InitializeComponent();                }                private void btnClickMe_Click(object sender, RoutedEventArgs e)                {                        lbResult.Items.Add(pnlMain.FindResource("strPanel").ToString());                        lbResult.Items.Add(this.FindResource("strWindow").ToString());                        lbResult.Items.Add(Application.Current.FindResource("strApp").ToString());                }        }}</span>

Resources grabbed from Code-behind

我们将 “Hello, world!” 放在三个不同的地方:App.xaml、窗口内部、本地panel。界面包含一个按钮和一个listbox。

在后台代码,我们处理按钮的点击事件,将三个不同地方的 “Hello, world!” 添加到ListBox中,如截屏所示。我们使用了FindResource()方法,将资源作为一个对象返回,然后用ToString()方法转换成字符串。
注意在FindResource()里,先访问panel,然后是窗口,最后是当前的应用对象。这对于寻找已知位置的资源非常有用。但是,如前面所述,如果资源找不到,那么会向上层搜索。所以原则上我们可以使用FindResource()在panel里访问三个地方,如果没有就会继续去窗口继而去应用层搜索。
反过来会怎么样呢?就不对了,你不能在窗口或者本地控件定义了资源,然后从应用层开始访问。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/128365.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • android布局文件详解

    android布局文件详解本文是我从DeclaringLayout翻译而来的文章,如果有不当之处请指出DeclaringLayout布局决定了Activity所展现的样子,他决定了布局的结构和控制着你展现给用户所有的元素,你可以通过两种方式来声明你的布局.①在xml文件中定义UI元素:android提供了与View类及其子类相关的简单易懂的标签。   ②在运行时期定义你的布局,即

    2022年6月2日
    53
  • 【Linux】vim的复制粘贴

    【Linux】vim的复制粘贴vim复制粘贴1.选定文本块。使用v进入可视模式,移动光标键选定内容。2.复制的命令是y,即yank(提起),常用的命令如下:y在使用v模式选定了某一块的时候,复制选定块到缓冲区用;yy复制整行(nyy或者yny,复制n行,n为数字);y^复制当前到行头的内容;y$复制当前到行尾的内容;yw复制一个word(nyw或者ynw,复制n个word,n为数字);yG复制至档尾(nyG或者ynG,复制到第n行,例如1yG或者y1G,复制到档尾)

    2022年9月16日
    2
  • C语言-函数-递归数列

    C语言-函数-递归数列题目:递归数列类别函数与递归程序类型:代码片段时间限制:2S内存限制10000Kb问题描述一个数列A定义如下A(1)=1,A(2)=1/(1+A(1)),A(3)=1/(1+A(2)),……A(n)=1/(1+A(n-1))。定义一个函数function用来计算数列的第第n项的值,函数声明如下:doublefunction(intn);输入说明:输入为1个…

    2025年10月28日
    3
  • Java基础(面向对象三大特性)

    Java基础(面向对象三大特性)目标:Java基础(面向对象三大特性)文章目录前言Java的三大特性?总结前言JAVA的地位Java具有面向对象、与平台无关、安全、稳定和多线程等优良特性,是目前软件设计中优秀的编程语言。提示:以下是本篇文章正文内容。Java的三大特性?1.封装性面向对象编程的核心思想之一是将数据的操作封装在一起。通过抽象,即从具体的实例中抽取出共同的性质形成一班的概念,例如类的概念。例如把生活中的一些行为称作是它们具有的方法,而属性是它们的状态描述,仅仅用属性或行为不能很好地描述它们。人们经常谈.

    2022年7月16日
    17
  • 俞敏洪沉默,新东方落泪

    俞敏洪沉默,新东方落泪据传,早些年以新东方三位创始人创业为主线故事,风靡一时的电影《中国合伙人》开拍前,剧组曾向电影男主角的原型人物俞敏洪,提出了友好交流的请求。俞敏洪提出最大的意见是:可不可以别把我拍得这么“土鳖”?几十年来,号称农村出身的寒门子弟俞敏洪,其身份发生了重大变化。在公开场合里,他对自己的身世表露出深深的自卑。另一方面,他又被誉为中国留学教父,俨然成为一个农村“凤凰男”逆袭成精英阶级的典型代表。当然,俞敏洪还是新东方的创始人,中国商业洪流里响当当的传奇。“我吃一碗兰州拉面都很开心”。可就是这样一个人,对财

    2025年11月7日
    4
  • 交叉熵损失函数原理详解[通俗易懂]

    交叉熵损失函数原理详解[通俗易懂]交叉熵损失函数原理详解之前在代码中经常看见交叉熵损失函数(CrossEntropyLoss),只知道它是分类问题中经常使用的一种损失函数,对于其内部的原理总是模模糊糊,而且一般使用交叉熵作为损失函数时,在模型的输出层总会接一个softmax函数,至于为什么要怎么做也是不懂,所以专门花了一些时间打算从原理入手,搞懂它,故在此写一篇博客进行总结,以便以后翻阅。交叉熵简介交叉熵是信息论中的一个…

    2022年6月26日
    33

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号