WPF真入门教程06--UI布局3

这一节中,继续前面的,代码都在前一节基础上增加的,这里操作下ListBox,Slider 滑动控件,DatePicker日期控件,TextBlock文字块,ProgressBar进度条,完整代码如下,控件有关属性都有注释。

<Window x:Class="WpfApp6.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp6"
        mc:Ignorable="d"
        Title="WPF基础控件" Height="758.275" Width="1078.5" Icon="images/22i.jpg" WindowStartupLocation="CenterScreen"  Loaded="Window_Loaded">
    <Grid Name="mygrid" >

        <Button Name="btnlogin"  IsDefault="True" Click="btnlogin_Click" Background="YellowGreen" BorderThickness="3"  BorderBrush="Red" Content="登录"  HorizontalAlignment="Left" Margin="166,95,0,0" VerticalAlignment="Top" Width="74" RenderTransformOrigin="-0.2,0.368"/>
        <Label Content="帐号" HorizontalAlignment="Left" HorizontalContentAlignment="Center" Margin="54,23,0,0" VerticalAlignment="Top" Width="102"/>
        <TextBox Name="txtname" HorizontalAlignment="Left" Height="23" Margin="142,23,0,0" TextWrapping="Wrap" Text="admin" VerticalAlignment="Top" Width="120"/>
        <Label Content="密码" HorizontalAlignment="Left" Margin="276,23,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.088,0.6"/>
        <PasswordBox Name="txtpass" HorizontalAlignment="Left" Height="22" Margin="330,23,0,0"  Password="123456" PasswordChar="#" VerticalAlignment="Top" Width="120"/>
        <Button Name="btncancle" IsCancel="True" Foreground="Chartreuse"  FontSize="14" Click="btncancle_Click" Content="取消" HorizontalAlignment="Left" Margin="266,95,0,0" VerticalAlignment="Top" Width="74">
            <Button.Background>
                <ImageBrush  ImageSource="images/32s.jpg"></ImageBrush>
            </Button.Background>
        </Button>
        <RadioButton Content="老师"  GroupName="role" HorizontalAlignment="Left" Margin="156,65,0,0" VerticalAlignment="Top" Checked="RadioButton_Checked"/>
        <RadioButton Content="学生"  GroupName="role" HorizontalAlignment="Left" Margin="230,65,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.14,0.357" Checked="RadioButton_Checked"/>
        <RadioButton Content="管理员"   GroupName="role" HorizontalAlignment="Left" Margin="303,65,0,0" VerticalAlignment="Top" Checked="RadioButton_Checked"/>
        <!-- IsThreeState属性指定 ToggleButton 是否有两种或三种状态:true,false,null,即选中 、清除 和不确定-->
        <CheckBox Content="汽车" Name="chkexcel" IsChecked="True" IsThreeState="True"  HorizontalAlignment="Left" Margin="45,138,0,0" VerticalAlignment="Top"/>
        <CheckBox Content="阅读"   HorizontalAlignment="Left" Margin="118,138,0,0" VerticalAlignment="Top"/>
        <CheckBox Content="唱歌" HorizontalAlignment="Left" Margin="181,138,0,0" VerticalAlignment="Top"/>
        <CheckBox Content="体育" HorizontalAlignment="Left" Margin="241,138,0,0" VerticalAlignment="Top"/>
        <Button Content="获取复选框" HorizontalAlignment="Left" Margin="301,135,0,0" VerticalAlignment="Top" Width="91" Click="Button_Click"/>
        <Button Content="创建复选框" HorizontalAlignment="Left" Margin="409,134,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click_1"/>
        <!--Image图片控件,Stretch指定拉伸模式 -->
        <Image HorizontalAlignment="Left"  Name="myimg" Height="83" Margin="45,184,0,0" VerticalAlignment="Top" Width="85" Source="images/6p.jpg" Stretch="Fill" RenderTransformOrigin="0.541,0.157"/>
        <Button Content="相对替换" HorizontalAlignment="Left" Margin="152,187,0,0" VerticalAlignment="Top" Width="69" Height="32" Click="Button_Click_2"/>
        <Button Content="绝对替换" HorizontalAlignment="Left" Margin="152,240,0,0" VerticalAlignment="Top" Width="69" Height="28" RenderTransformOrigin="0.536,0.815" Click="Button_Click_3"/>
        <!-- Border边框控件,与布局面板一起使用,里面只能有一个子元素,BorderThickness边框粗细,BorderBrush边框颜色,CornerRadius圆角大小,Background背景色-->
        <Border BorderBrush="red" BorderThickness="3" HorizontalAlignment="Left" Height="32" Margin="266,184,0,0" VerticalAlignment="Top" Width="100">
            <Label Content="我有边框" HorizontalAlignment="Center" VerticalAlignment="Center"/>
        </Border>
        <Border BorderBrush="BlueViolet" BorderThickness="5" CornerRadius="9" Background="Bisque" HorizontalAlignment="Left" Height="38" Margin="266,229,0,0" VerticalAlignment="Top" Width="100">
            <Label Content="我有圆角" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="16,1,16,3"/>
        </Border>
        <!--ComboBox下拉框,IsDropDownOpen指定是否展开,默认不展开 -->
        <ComboBox HorizontalAlignment="Left" Name="hecbm" IsDropDownOpen="False" Margin="403,187,0,0" VerticalAlignment="Top" Width="81" Height="22">
            <ComboBoxItem Content="请选择" IsSelected="True" Background="#FF26D365"/>
            <ComboBoxItem Content="亚洲"/>
            <ComboBoxItem Content="非洲"/>
            <ComboBoxItem Content="欧洲"/>
        </ComboBox>
        <ComboBox Name="mycbm" HorizontalAlignment="Left" Margin="403,241,0,0" VerticalAlignment="Top" Width="81" Height="27" RenderTransformOrigin="0.247,0.481"/>
        <!--ListBox列表控件,IsSelected表示是否选中-->
        <ListBox HorizontalAlignment="Left" Height="95" Margin="45,290,0,0" VerticalAlignment="Top" Width="100" RenderTransformOrigin="0.21,0.484">
            <ListBoxItem Content="茶杯" IsSelected="True"/>
            <ListBoxItem Content="茶叶"/>
            <ListBoxItem Content="茶水"/>
            <ListBoxItem Content="茶桌"/>
        </ListBox>
        <!--这个列表数据由在Window_Loaded动态添加列表框数据源-->
        <ListBox Name="mylist" HorizontalAlignment="Left" Height="95" Margin="166,290,0,0" VerticalAlignment="Top" Width="100"/>
        <!-- DatePicker日期控件-->
        <DatePicker Focusable="False"  HorizontalAlignment="Left"  Margin="301,290,0,0" VerticalAlignment="Top" Width="106" SelectedDateFormat="Long" />
        <!--Slider 滑动控件,Orientation刻度方向(默认水平),TickPlacement刻度位置(默认没有):both/left/right/none,TickFrequency刻度间隔,IsSnapToTickEnabled表示数值变化形式(true代表整形,false代表浮点)-->
        <Slider Name="sd1" HorizontalAlignment="Left" Margin="303,327,0,0" TickPlacement="Both" TickFrequency="1" IsSnapToTickEnabled="true" Maximum="100" Minimum="1" Value="1" VerticalAlignment="Top" Width="104"/>
        <!--Label控件, Content指定内容:Binding绑定,ElementName绑定控件名称,Path绑定控件的value值,Mode=OneWay指单向影响-->
        <Label Content="当前值:" HorizontalAlignment="Left" Margin="304,362,0,0" VerticalAlignment="Top"/>
        <Label Content="{Binding ElementName=sd1,Path=Value,Mode=OneWay}" Name="mylbl" HorizontalAlignment="Left" Margin="360,362,0,0" VerticalAlignment="Top" Width="47"/>
        <Slider HorizontalAlignment="Left" Name="sd2" Margin="421,282,0,0" TickPlacement="BottomRight" TickFrequency="5"  Orientation="Vertical" Maximum="100" Minimum="1" Value="10" VerticalAlignment="Top" Height="103" Width="33" Background="#FFCCFB2D" BorderBrush="#FF4118B0"/>
        <!--TextBlock文字块 -->
        <TextBlock FontSize="{Binding ElementName=sd2,Path=Value,Mode=OneWay}"  HorizontalAlignment="Left"  Margin="459,290,0,0" TextWrapping="Wrap" Text="看我" VerticalAlignment="Top" Height="86" Width="61"/>
        <!--ProgressBar进度条:Orientation方向(Horizontal/Vertical,水平/垂直),IsIndeterminate指定连续进度 -->
        <ProgressBar  Orientation="Horizontal"  IsIndeterminate="true" Value="30"  HorizontalAlignment="Left" Height="18" Margin="48,394,0,0" VerticalAlignment="Top" Width="327"/>
        <ProgressBar Name="ps2"  Orientation="Vertical" Value="0" Minimum="0" Maximum="120" HorizontalAlignment="Left" Height="149" Margin="402,394,0,0" VerticalAlignment="Top" Width="29"/>
        <Button Content="加载进度" HorizontalAlignment="Left" Margin="441,434,0,0" VerticalAlignment="Top" Width="60" Click="Button_Click_4"/>
        <Label Content="当前:" HorizontalAlignment="Left" Margin="438,469,0,0" VerticalAlignment="Top"/>
        <Label Content="" Name="ps2lbl" HorizontalAlignment="Left" Margin="474,469,0,0" VerticalAlignment="Top"/>
         
    </Grid>
</Window>

第二步,在后台cs文件编写代码,完整代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApp6
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void btncancle_Click(object sender, RoutedEventArgs e)
        {

        }

        private void btnlogin_Click(object sender, RoutedEventArgs e)
        {
            string uname = txtname.Text.Trim();
            string passwd = txtpass.Password.Trim();
            MessageBox.Show("登录成功","登录提示",MessageBoxButton.OK,MessageBoxImage.Information);
        }

        private void RadioButton_Checked(object sender, RoutedEventArgs e)
        {
            string t = (sender as RadioButton).Content.ToString();
            MessageBox.Show(t);
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            //动态添加一个单选按钮
            RadioButton radbtn = new RadioButton();
            radbtn.Content = "主任";
            radbtn.GroupName = "role";
            radbtn.HorizontalAlignment = HorizontalAlignment.Left;
            radbtn.VerticalAlignment = VerticalAlignment.Top;
            radbtn.Margin = new Thickness(375,64, 0, 0);
            radbtn.Checked += RadioButton_Checked;//指定事件处理
            mygrid.Children.Add(radbtn);
            //动态指定下拉框数据源
            List<string> listinfo = new List<string>();
            listinfo.Add("请选择");
            listinfo.Add("南京");
            listinfo.Add("桂林");
            listinfo.Add("深圳");
            listinfo.Add("沈阳");
            mycbm.ItemsSource = listinfo;
            mycbm.SelectedIndex =2;
            //动态添加列表框数据源
            listinfo.RemoveAt(0);
            mylist.ItemsSource = listinfo; 
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            //获取所有勾选的复选框的内容
            string txt = "";
            foreach(UIElement ele in mygrid.Children)
            {
                if(ele is CheckBox)
                {
                    CheckBox chk = ele as CheckBox;
                    if(chk.IsChecked==true)
                    {                       
                        txt += chk.Content.ToString();
                        txt += ",";
                    }
                }
            }
            MessageBox.Show(txt.TrimEnd(','));//TrimEnd去掉最后一个字符
        }

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            string[] excel = { "足球", "兰球", "铁球" };
            for(int i=0;i<excel.Length;i++)
            {
                CheckBox chkitem = new CheckBox();
                chkitem.Content = excel[i];
                chkitem.HorizontalAlignment = HorizontalAlignment.Left;
                chkitem.VerticalAlignment = VerticalAlignment.Top;
                chkitem.Margin = new Thickness(40 + i *60, 160, 0, 0);
                mygrid.Children.Add(chkitem);
            }
        }

        private void Button_Click_2(object sender, RoutedEventArgs e)
        {
            //相对路径,UriKind.Relative路径类型
            myimg.Source = new BitmapImage(new Uri("/images/80zj.jpg",UriKind.Relative));
        }

        private void Button_Click_3(object sender, RoutedEventArgs e)
        {
            //绝对路径,AppDomain.CurrentDomain.BaseDirectory表示当前程序的运行路径
            myimg.Source = new BitmapImage(new Uri(AppDomain.CurrentDomain.BaseDirectory+"/imgs/3sk.jpg",UriKind.Absolute));
        }

        /// <summary>
        /// 加载进度
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button_Click_4(object sender, RoutedEventArgs e)
        {
            double max = ps2.Maximum;
            //task异步执行任务
            Task.Run(()=>
            {
                for (int i = 0; i <= max; i++)
                { 
                    ps2.Dispatcher.Invoke(()=> 
                    {
                        ps2.Value = i;
                        ps2lbl.Content = ps2.Value.ToString()+"%"; 
                    });
                    Thread.Sleep(100);
                } 
            });
           
        }
    }
}

这里代码中用到了线程更新ui,涉及到了Dispatcher,它的作用是用于管理线程工作项队列,这个是难点,下面详细介绍下。

一、Dispatcher介绍

       微软在WPF引入了Dispatcher,那么这个Dispatcher的主要作用是什么呢?

       不管是WinForm应用程序还是WPF应用程序,实际上都是一个进程,一个进程可以包含多个线程,其中有一个是主线程,其余的是子线程。在WPF或WinForm应用程序中,主线程负责接收输入、处理事件、绘制屏幕等工作,为了使主线程及时响应,防止假死,在开发过程中对一些耗时的操作、消耗资源比较多的操作,都会去创建一个或多个子线程去完成操作,比如大数据量的循环操作、后台下载。这样一来,由于UI界面是主线程创建的,所以子线程不能直接更新由主线程维护的UI界面。

       Dispatcher的作用是用于管理线程工作项队列。类似于Win32中的消息队列,Dispatcher的内部函数,仍然调用了传统的创建窗口类,创建窗口,建立消息泵等操作。Dispatcher本身是一个单例模式,构造函数私有,暴露了一个静态的CurrentDispatcher方法用于获得当前线程的Dispatcher。对于线程来说,它对Dispatcher是一无所知的,Dispatcher内部维护了一个静态的 List

二、Dispatcher的继承关系

       在 WPF 的类层次结构中,大部分都集中派生于 DispatcherObject 类(通过其他类)。如下图 所示,您可以看到 DispatcherObject 虚拟类正好位于 Object 下方和大多数 WPF 类的层次结构之间。 要了解他们之间的关系可以参看下面这张类继承关系图: 

对上图的一些说明:

1)  System.Object 类:大家都知道在.Net中所有类型的基类,DispatcherObject 就继承于它,所以它是WPF的基类。

2)  System.Windows.Threading.DispatcherObject 类:从图中看WPF 中的使用到的大部分控件与其他类大多是继承 DispatcherObject 类,它提供了用于处理并发和线程的基本构造。

3)  System.Windows.DependencyObject类:对WPF中的依赖项属性承载支持与  附加属性承载支持,表示参与 依赖项属性 系统的对象。

4)  System.Windows.Media.Visual类:为 WPF 中的呈现提供支持,其中包括命中测试、坐标转换和边界框计算等。

5)  System.Windows.UIElement 类:UIElement 是 WPF 核心级实现的基类,该类是 Windows Presentation Foundation (WPF) 中具有可视外观并可以处理基本输入的大多数对象的基类。

6)  System.Windows.FrameworkElement类:为 Windows Presentation Foundation (WPF) 元素提供 WPF 框架级属性集、事件集和方法集。此类表示附带的 WPF 框架级实现,它是基于由UIElement定义的 WPF 核心级 API 构建的。

7)  System.Windows.Controls.Control 类:表示 用户界面 (UI) 元素的基类,这些元素使用 ControlTemplate 来定义其外观。

8)  System.Windows.Controls.ContentControl类:表示没有任何类型的内容表示单个控件。

WPF的绝大部分的控件,还包括窗口本身都是继承自ContentControl的。

 9)  System.Windows.Controls.ItemsControl 类:表示可用于提供项目的集合的控件。 

10) System.Windows.Controls.Panel类:为所有 Panel 元素提供基类。 使用 Panel 元素定位和排列在 Windows Presentation Foundation (WPF) 应用程序的子对象。

11)System.Windows.Sharps.Sharp类:为 Ellipse、Polygon 和 Rectangle 之类的形状元素提供基类。

三、走进Dispatcher

      所有 WPF 应用程序启动时都会加载两个重要的线程:一个用于呈现用户界面,另一个用于管理用户界面。呈现线程是一个在后台运行的隐藏线程,因此您通常面对的唯一线程 就是 UI 线程。WPF 要求将其大多数对象与 UI 线程进行关联。这称之为线程关联,意味着要使用一个 WPF 对象,只能在创建它的线程上使用。在其他线程上使用它会导致引发运行时异常。 UI 线程的作用是用于接收输入、处理事件、绘制屏幕以及运行应用程序代码。

      在 WPF 中绝大部分控件都继承自 DispatcherObject,甚至包括 Application。这些继承自 DispatcherObject 的对象具有线程关联特征,也就意味着只有创建这些对象实例,且包含了 Dispatcher 的线程(通常指默认 UI 线程)才能直接对其进行更新操作。

      DispatcherObject 类有两个主要职责:提供对对象所关联的当前 Dispatcher 的访问权限,以及提供方法以检查 (CheckAccess) 和验证 (VerifyAccess) 某个线程是否有权访问对象(派生于 DispatcherObject)。CheckAccess 与 VerifyAccess 的区别在于 CheckAccess 返回一个布尔值,表示当前线程是否可以使用对象,而 VerifyAccess 则在线程无权访问对象的情况下引发异常。通过提供这些基本的功能,所有 WPF 对象都支持对是否可在特定线程(特别是 UI 线程)上使用它们加以确定。如下图。

 

在 WPF 中,DispatcherObject 只能通过与它关联的 Dispatcher 进行访问。 例如,后台线程不能更新由 UI 线程创建的 Label的内容。那么如何更新UI线程创建的对象信息呢?Dispatcher提供了两个方法,Invoke和BeginInvoke,这两个方法还有多个不同参数的重载。其中Invoke内部还是调用了BeginInvoke,一个典型的BeginInvoke参数如下: 

public DispatcherOperation BeginInvoke(Delegate method, DispatcherPriority priority, params object[] args); 

Invoke 是同步操作,而 BeginInvoke 是异步操作。 该这两个操作将按指定的 DispatcherPriority 添加到 Dispatcher 的队列中。 DispatcherPriority定义了很多优先级,可以分为前台优先级和后台优先级,其中前台包括 Loaded~Send,后台包括Background~Input。剩下的几个优先级除了Invalid和Inactive都属于空闲优先级。这个前台优先级和后台优先级的分界线是以Input来区分的,这里的Input指的是键盘输入和鼠标移动、点击等等。

DispatchPriority 优先级别

        Invalid:这是一个无效的优先级。

        Inactive:工作项目已排队但未处理。

        SystemIdle:仅当系统空闲时才将工作项目调度到 UI 线程。这是实际得到处理的项目的最低优先级。

        ApplicationIdle:仅当应用程序本身空闲时才将工作项目调度到 UI 线程。

        ContextIdle:仅在优先级更高的工作项目得到处理后才将工作项目调度到 UI 线程。

        Background:在所有布局、呈现和输入项目都得到处理后才将工作项目调度到 UI 线程。

        Input:以与用户输入相同的优先级将工作项目调度到 UI 线程。

        Loaded:在所有布局和呈现都完成后才将工作项目调度到 UI 线程。

        Render:以与呈现引擎相同的优先级将工作项目调度到 UI 线程。

        DataBind:以与数据绑定相同的优先级将工作项目调度到 UI 线程。

        Normal:以正常优先级将工作项目调度到 UI 线程。这是调度大多数应用程序工作项目时的优先级。

        Send:以最高优先级将工作项目调度到 UI 线程。

四、使用Dispatcher

 

五、小结

     在WPF中,所有的WPF对象都派生自DispatcherObject,DispatcherObject暴露了Dispatcher属性用来取得创建 对象线程对应的Dispatcher。DispatcherObject对象只能被创建它的线程所访问,其他线程修改 DispatcherObject需要取得对应的Dispatcher,调用Invoke或者BeginInvoke来投入任务。Dispatcher的一些设计思路包括 Invoke和BeginInvoke等从WinForm时代就是一直存在的,只是使用了Dispatcher来封装这些线程级的操作。

第三步,运行程序,

 推动滑动条,值会变化,同时那个textblock文字会变大或变小

点击"加载进度“,进度条会变化,这就是异动更新时用到了Dispatcher技术,

在这个例子中,Invoke,Dispatcher是个难点,涉及到异步多线程,任务task,还有委托概念,这块不展开讲,请自行熟悉。

今天到此,又是苦逼的编者,向大伽致敬。

 


                
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
### 回答1: WPF(Windows Presentation Foundation)是微软发布的一种创建图形用户界面的技术,它结合了XAML(可扩展应用程序标记语言)和各种.NET语言(如VB.NET)来构建交互式应用程序。如果您想学习WPF,以下是一些入门教程: 1. 官方文档:微软提供了一份详细的WPF文档,其中包括了从基础入门到高级特性的介绍,这将是您开始学习WPF的最佳选择。 2. MSDN教程:在MSDN社区中,有大量的WPF教程和文章,涵盖了从XAML基础到如何使用数据绑定和动画等高级功能的内容。 3. 视频教程:还有许多视频教程可以帮助您学习WPF,这些视频教程可以找到许多网站,比如Pluralsight和Lynda等。 4. 书籍:如果您更喜欢看书学习,这里有几本非常不错的WPF入门书籍,如“WPF入门指南”,“Visual Basic 2015 Unleashed”等。 5. 示例代码:最后,一些示例代码可能会对您的学习有所帮助,您可以使用微软提供的Visual Studio IDE(集成开发环境)来开发WPF应用程序,同时它还提供了许多WPF应用程序模板。 综上所述,这些都是WPF入门教程的主要来源,以及一些有用的资源,如果您想掌握WPF技术,最好的方法是自己动手,尝试编写WPF应用程序,多看文档和教程,并实践一些示例代码。 ### 回答2: WPF是一个新型的Windows桌面应用程序开发平台,它提供了一种基于XAML的声明式UI编程模型,使得开发者可以轻松地创建强大、灵活和现代化的用户界面。对于初学者而言,学习WPF需要掌握一些基本的概念,如XAML的语法、WPF的控件、布局、样式和绑定等等。 VB是一种流行的面向对象的编程语言,也是WPF的一种开发语言。在学习WPF时,掌握VB语言及基本的编程概念是必不可少的。要开始学习WPF,建议首先了解如何创建WPF应用程序以及如何使用Visual Studio来编写代码。 在WPF中,控件是应用程序的基本结构单元。可以使用各种控件来构建用户界面,包括按钮、标签、输入框、列表框、网格和文本框等等。控件可以使用样式来自定义其外观和样式,并使用绑定来实现数据绑定和交互。 在WPF中,还有一些高级的概念和功能,如路由事件、命令、动画和绘图等等,这些都可以让你创建出更加复杂和丰富的应用程序。建议在学习初期,专注于掌握基本的概念和语法,逐步深入学习和了解更多的高级功能,并使用实际的项目来练习和掌握WPF的技能和知识。 ### 回答3: WPF(Windows Presentation Foundation)是一个基于.NET框架的图形用户界面开发工具,它提供了一种新的方式来创建用户界面,使开发人员可以快速地创建富客户端应用程序。WPF入门教程适合有一定VB.NET编程基础的开发人员,以下是一些具体的学习建议: 第一步,建立基本的WPF应用程序框架。学习如何创建WPF应用程序,如何设置不同的前景、背景色、各种控件的大小和位置等。可以试着创建一些简单的窗口控件,并在其中添加一些基本的控件,比如文本框、标签等。 第二步,学习WPF控件。WPF提供了许多控件,如文本框、标签、按钮、列表框等等。学习每个控件的属性和事件,了解每个控件的特点和使用场景。 第三步,学习WPF布局WPF提供了多种方式来布局控件,如栅格布局、StackPanel布局、WrapPanel布局等等。学习每种布局方式的特点和使用场景,如何设置控件在布局中的位置和大小等。 第四步,学习WPF绑定。WPF提供了一种数据绑定机制,可以将控件与数据源进行绑定,使数据源发生变化时,控件能够自动更新。学习绑定的基本语法和使用方法,并了解如何将不同类型的数据绑定到控件上。 第五步,学习WPF模板。WPF提供了一种模板机制,可以自定义控件的样式和布局。学习如何创建和使用控件模板,让控件的外观和功能更加灵活。 总之,学习WPF需要耐心和实践,多做一些练习和实践项目,逐渐提升自己的技能。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hqwest

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值