• WPF基础知识、界面布局及控件Binding(转)


    WPF是和WinForm对应的,而其核心是数据驱动事件,在开发中显示的是UI界面和逻辑关系相分离的一种开放语言。UI界面是在XAML语言环境下开发人员可以进行一些自主设计的前台界面,逻辑关系还是基于c#语言进行的逻辑设计。在使用WPF做项目的时候,免不了要对界面进行布局,同时需要对其中的控件进行绑定,本文主要是对这几方面进行介绍。

    首先介绍WPF的基础知识:

    1 XAML是什么?

    XAML(Extensible Application Markup Language)即可扩展应用程序标记语言,是WPF技术中专门用于设计UI的语言。

    2、XAML的文档结构?

    在程序员眼中,UI界面只是一个平面结构。但是从后台XAML代码中看来,UI界面实际上是一个树形逻辑结构。

    3、XAML中属性元素的理解?

    属性元素指的是某个标签的一个元素对应的这个标签的一个属性,即以元素的形式来表达一个实例的属性。XAML为对象属性赋值语法有两种:使用字符串进行简单赋值;使用属性元素进行复杂赋值。例如:

    <Grid VerticalAlignment="Center" HorizontalAlignment="Center" >

            <Rectangle x:Name="rectangle" Width="200" Height="120">

                <Rectangle.Fill >

                    <SolidColorBrush Color="Blue" />

                </Rectangle.Fill >

            </Rectangle>

        </Grid >

    4、XAML中的标记扩展?

    标记扩展就是一种特殊的Attribute=Value,特殊处在于Value是由一对花括号及其括起来的内容组成。XAML编译器会对这样的内容作出解析、生成相应的对象。

    5、WPF中事件处理器?

    WPF支持在XAML里为对象的事件指定事件处理器,方法是使用事件处理器的函数名为对应对象事件的Attribute进行赋值。例如:

    <Button x:Name="button1" Click=" button1_Click" Margin="5" Height="15" Width="50"/>

    6、在自己的程序里引用类库?

    步骤需要三步:

    1编写类库项目并编译得到.dll文件或者获得别人编译的.dll文件。

    2将类库项目或者.dll文件中引用自己的项目

    3在c#和XAML中引用类库中的名称空间。

    7、XAML注释语法?

    <!—注释内容-->

    9、 XAML中X名称空间?

    X名称空间映射的是xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml

    <Rectangle x:Name="rectangle" Width="200" Height="120">

                <Rectangle.Fill >

                    <SolidColorBrush Color="Blue" />

                </Rectangle.Fill >

            </Rectangle>

    10、X名称空间大致可分为三类?

    Attribute:是语言层面的东西、是给编译器看的。(Property是面向对象层面的东西,是给编程逻辑用的)

    标记扩展:实际上就是一些MarkupExtension类的直接或者间接派生类。X名称空间中就包含这样的类。

    XAML指令元素:有x:Code,x:XData。

    11、WPF中控件?

    经常用到的6类:

    1 布局控件 可以容纳多个控件或嵌套其他布局控件,用于在UI上组织和排列控件。常用的Grid、StackPanel、DockPanel,共同父类是Panel。

     2 内容控件 只能容纳一个其他控件。父类是ContentControl。

     3 带标题内容的控件 就是一个内容控件+一个标题,标题部分可容纳一个控件或布局。

     4 条目控件 可以显示一列数据,共同父类是ItemsControl。

     5 带标题条目控件 就是一个条目控件+一个标题显示区。基类是HeaderedItemsControl。

     6 特殊内容控件

    12、WPF精髓?

    WPF是数据驱动UI,数据是核心、主动的,UI属于数据并表达数据、被动的

    13、Binding是什么?

    在WPF中,Binding是架在目标(UI层控件对象)和源(逻辑层对象)之间的一座桥梁。

    14、Binding对源的要求是:只要它是一个对象,并且通过属性公开自己的数据,它就能作为Binding的源。

    15、Binding的方向即Binding模式有哪些?

    Binding模式有OneWay、TwoWay、OnTime、OneWayToSource、Default。

    OneWay:每当源发生变化时,数据就会从源流向目标。

    TwoWay:绑定会将源数据发送到目标,但如果目标属性发生变化,则会将变化发回给源。

    OnTime:绑定会将源数据发送到目标,但是仅当启动了应用程序或DataContext发生更改时才会有这个操作,所以它不会侦听源中的更改通知。

    OneWayToSource:绑定会将源数据发送到目标。

    Default:根据实际情况来定,可编辑的就是TwoWay,只读的就是OneWay。在连接没有设置模式时就是Ddfault。

    16、Binding的路径(Path)和没有Path的情况?

    Binding的路径设置有很多种,其中最简捷的就是直接把Binding关联在Binding源上。

    <TextBox x:Name=”textBox1” Text={Binding Path=Value, ElementName=slider1}/>

    没有Path的情况就是Binding源本身就是数据且不需要Path来指明。

    17、为Binding指定Source的几种方法?没有Source的情况?

    (几种方法,在这里不一一罗列,但是没有实际用过。)

    没有Source的情况就是使用DataContext作为Binding的源。

    18、Binding的数据校验?Binding的数据转换?

    Binding数据有效性校验是它的ValidationRules属性,Binding数据转换是它的Converter属性。

    19、模板 Template?

    ControlTemplate是算法内容的表现形式;DataTemplate是数据内容的表现形式

    20、DataTemplate常用到的3个地方:

    ContentControl的ContentTemplate属性,ItemsControl的ItemTemplate属性,GrdiViewColumn的CellTemplate属性。

    WPF界面布局

    在WPF做项目过程中,需要对界面元素进行合理布局,以便系统更人性化。WPF提供了一套强有力的工具:面板panel。下面将逐一介绍这些面板的使用方法。

    Grid

      网格面板,以表格形式布局元素,对于整个面板上的元素进行布局,有效地解决多行之间、多列之间位置的一致性。Grid很像网页中的Table,定义一个网格,需要定义行、列,划分单元格,坐标从(0,0)开始。列宽和行高,分别可以在ColumnDefinition、RowDefinition里面指定Width、Height的值。首先定义网格,然后定义元素,并指定元素所在的单元格。如果不定义单元格,默认将元素放到第一个单元格(0,0)。自动长度——自动匹配列中最长元素的宽度;比例长度——*表示占用剩余的全部宽度;两行都是*,将平分剩余宽度;一个2*,一个*,表示前者2/3宽度。使用Grid.ColumnSpan和Grid.RowSpan附加属性可以让相互间隔的行列合并,使用GridSplit控件结合Grid控件实现类似于WinForm中SplitContainer的功能。

    复制代码
    <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="44*" />
                <ColumnDefinition Width="141*" />
                <ColumnDefinition Width="218*" />
                <ColumnDefinition Width="122*" />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="62*" />
                <RowDefinition Height="70*" />
                <RowDefinition Height="102*" />
                <RowDefinition Height="116*" />
            </Grid.RowDefinitions>
            <Button Content="Button" Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="16,18,0,0" Name="button1" VerticalAlignment="Top" Width="75" Grid.Column="1" />
            <Button Content="Button" Grid.Column="1" Grid.ColumnSpan="2" Grid.Row="2" Height="23" HorizontalAlignment="Left" Margin="107,38,0,0" Name="button2" VerticalAlignment="Top" Width="75" />
            <Button Content="Button" Grid.Row="3" Height="23" HorizontalAlignment="Left" Margin="16,38,0,0" Name="button3" VerticalAlignment="Top" Width="396" Grid.ColumnSpan="3" Grid.Column="1" />
        </Grid>
    复制代码


     

    复制代码
    <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="102" />
                <ColumnDefinition Width="161" />
                <ColumnDefinition Width="15" />
                <ColumnDefinition Width="Auto" />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="66" />
                <RowDefinition Height="96" />
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>
        </Grid>
    复制代码

    Canvas

      画布,用于完全控制每个元素的精确位置。它是布局控件中最为简单的一种,直接将元素放到指定位置,主要来布置图画。使用Canvas时,必须指定一个字元素的位置(相对于画布),否则所有元素都将出现在画布的左上角。调整位置用Left、Right、Top和Bottom四个附加属性。如果Canvas是窗口主元素,用户改变窗口大小时,Canvas也会随之变化,字元素的位置也会随之移动,以保证相对于Canvas的位置属性不变。Canvas允许子元素的部分或全部超过其边界,默认不会剪裁子元素,同时可以使用负坐标,因此画布不需要指定大小。如果想复制画布内容,将ClipToBounds设为true即可。

    复制代码
    <Grid>
            <Canvas Height="280" HorizontalAlignment="Left" Margin="22,32,0,0" Name="canvas1" VerticalAlignment="Top" Width="482" Background="Gray">
                <Canvas Canvas.Left="46" Canvas.Top="58" Height="100" Name="canvas2" Width="200" Background="Red">
                    <Ellipse Canvas.Left="82" Canvas.Top="20" Height="100" Name="ellipse1" Stroke="Black" Width="200" Fill="White"  />
                </Canvas>
                <Canvas Canvas.Left="295" Canvas.Top="184" Height="64" Name="canvas3" Width="143" Background="Green" ClipToBounds="True" >
                    <Ellipse Canvas.Left="24" Canvas.Top="7" Height="100" Name="ellipse2" Stroke="Black" Width="200" Fill="White"  />
                </Canvas >
            </Canvas>
        </Grid>
    复制代码

    StackPanel

      栈面板,可以将元素排列成一行或者一列。其特点是:每个元素各占一行或者一列。Orientation属性指定排列方式:Vertical(垂直)【默认】、Horizontal(水平)。默认情况下,水平排列时,每个元素都与面板一样高;垂直排列时,每个元素都与面板一样宽。如果元素超过了StackPanel的空间,会截断多出的内容。 元素的Margin属性用于使元素之间产生一定得间隔,当元素空间大于其内容的空间时,剩余空间将由HorizontalAlignment和VerticalAlignment属性来决定如何分配。

    复制代码
    <Grid>
            <StackPanel Height="144" HorizontalAlignment="Left" Margin="33,21,0,0" Name="stackPanel1" VerticalAlignment="Top" Width="346">
                <Button Content="Button" Height="23" Name="button1" Width="75" />
                <Button Content="Button" Height="23" Name="button2" Width="235" />
                <Button Content="Button" Height="23" Name="button3" Width="658" />
            </StackPanel>
            <StackPanel Height="155" HorizontalAlignment="Left" Margin="45,179,0,0" Name="stackPanel2" VerticalAlignment="Top" Width="401" Orientation="Horizontal"  >
                <Button Content="Button" Height="23" Name="button4" Width="75" />
                <Button Content="Button" Height="23" Name="button5" Width="75" />
            </StackPanel>
        </Grid>
    复制代码

    WrapPanel

      从左至右或从上至下按顺序位置定位子元素,如果排满则自动换行至下一行或列继续排列。WrapPanel面板也提供了 Orientation属性设置排列方式,属性设置横排(Horizontal默认)和竖排(Vertical)。

    复制代码
    <Grid>
            <WrapPanel Height="129" HorizontalAlignment="Left" Margin="50,36,0,0" Name="wrapPanel1" VerticalAlignment="Top" Width="260">
                <Button Content="Button" Height="23" Name="button1" Width="75" />
                <Button Content="Button" Height="23" Name="button2" Width="75" />
                <Button Content="Button" Height="23" Name="button3" Width="75" />
                <Button Content="Button" Height="23" Name="button4" Width="75" />
            </WrapPanel>
            <WrapPanel Height="105" HorizontalAlignment="Left" Margin="99,195,0,0" Name="wrapPanel2" VerticalAlignment="Top" Width="211" Orientation="Vertical" >
                <Button Content="Button" Height="23" Name="button5" Width="75" />
                <Button Content="Button" Height="23" Name="button6" Width="75" />
            </WrapPanel>
        </Grid>
    复制代码

    DockPanel

      停靠面板,可以将面板的某一边指定给每个元素,当面板大小变化时,按钮将根据指定的边进行停靠。在DockPanel中,指定停靠边的控件,会根据定义的顺序占领边角,所有控件绝不会交叠。默认情况下,后添加的元素只能使用剩余空间,最后一个元素填充所有剩余空间。如果不希望最后一个元素填充剩余区域,可以将DockPanel属性LastChildFill设置为False。

      DockPanel面板可以将子元素停靠在面板的上下左右。DockPanel会对每个子元素进行排序,并停靠在面板的一侧,多个停靠在同侧的元素则按顺序排序,最后一个元素填充这个Panel(这个需要设置LastChildFill属性为 True)。对于在DockPanel中的元素的停靠属性可以通过Panel.Dock的附加属性来设置。

    复制代码
    <Grid>
            <DockPanel Height="100" HorizontalAlignment="Left" Margin="43,44,0,0" Name="dockPanel1" VerticalAlignment="Top" Width="281" LastChildFill="False"  >
                <Button Content="Button" Height="23" Name="button1" Width="75" />
                <Button Content="Button" Height="23" Name="button2" Width="75" />
                <Button Content="Button" Height="23" Name="button3" Width="75" />
            </DockPanel>
            <DockPanel Height="141" HorizontalAlignment="Left" Margin="140,183,0,0" Name="dockPanel2" VerticalAlignment="Top" Width="299">
                <Button Content="Button" Height="23" Name="button4" Width="75" />
                <Button Content="Button" Height="23" Name="button5" Width="75" />
                <Button Content="Button" Height="23" Name="button6" Width="75" />
            </DockPanel>
        </Grid>
    复制代码

    视图框(Viewbox

      视图框可以自动缩放其内容,以填充可用的空间。它只能有一个子元素。比如,Viewbox中放置一个Canvas,默认将按比例缩放Canvas,填充区域,而此时Canvas指定的长宽已不起作用,仅保留比例。如果想禁用Viewbox的自动缩放功能,将其拉伸属性Stretch设置为None即可;如果想缩放并且不保留子元素比例,将Viewbox的Stretch属性(默认为Uniform)改为Fill(完全填充);如果想保留比例并完全填充空白区域,Stretch设置为UniformToFill。

    上图分别是stretch:Stretch="Fill", Stretch="None",Stretch="Uniform",Stretch="UniformToFill"

    <Grid>
            <Canvas Height="261" HorizontalAlignment="Left" Margin="34,22,0,0" Name="canvas1" VerticalAlignment="Top" Width="416">
                <Viewbox Canvas.Left="29" Canvas.Top="18" Height="218" Name="viewbox1" Width="348" Stretch="UniformToFill"        >
                    <Button Content="Button" Height="23" Name="button1" Width="75" />
                </Viewbox>
            </Canvas>
        </Grid>

    Border

    Border 是一个装饰的控件,此控件绘制边框及背景,在 Border 中只能有一个子控件(这个子控件又可以包含多个子控件)。

    <Grid>
            <Border  BorderThickness="20" BorderBrush="Green"  Height="230" HorizontalAlignment="Left" Background="Red"  Margin="35,40,0,0" Name="border1" VerticalAlignment="Top" Width="447"  />
        </Grid>

    滚动视图控件(ScrollViewer

      滚动视图控件可以将过多的内容放入一个可滚动的区域来显示。比如一个很大的椭圆,通过滚动就可以显示全部内容。但是ScollViewer只能放一个元素,这个元素是任意的。倘若想布局多个元素,可以将多个元素放到一个面板中,再嵌入到ScollViewer中。

    滚动条的可见性,默认垂直滚动条是可见的(Visiable),而水平滚动条是不可用的(Disable),此处改为Auto(需要时显示)或者Visiable(可见,不论需不需要都显示)。

    UniformGrid

      均布网格, 顾名思义,所有单元格均匀排布,大小都相同。你可以为其指定行数Rows和列数Columns,UniformGrid将根据行列平分画布,每个控件一个单元格。如果不指定其行数和列数,UniformGrid会根据子元素个数和大小,默认创建相同的行数和列数,布局所有子元素。由于每个单元格只包含一个子元素,不需要额外指定哪个元素属于哪个单元格,所以直接添加子元素就可以。

    公共布局属性

      Width、Height表示元素宽度和高度,设置该属性可以是元素具有精确的宽高。MinWidth、MaxWidth、MinHeight、MaxHeight 可以指定元素大小的界限,分别表示元素的最小宽度、最大宽度、最小高度和最大高度。当你指定一个元素的宽度和高度时,WPF会尽可能遵循你的设置。比如元素宽度>屏幕宽度,元素将被剪裁以适应可用空间。

      Margin(外边距),指的是元素周围的距离,决定了元素周围留下的空白大小;Padding(内边距),指的是元素边界与其内容之间的距离。做过网页设计、用过CSS的同学对margin和padding属性肯定不陌生,但也有所区别。WPF中的Margin值可以为一个数字、一对数字和四个数字。

      一个数字代表四周距离相同,为指定值。一对数字时,第一个数字表示左侧和右侧距离相同,为指定值;第二个数字表示顶部和底部距离相同,为指定值。(与CSS中顺序不同)。四个数字,分别表示左侧、顶部、右侧、底部距离,该顺序与CSS不同。

    CSS中margin和padding属性顺序是:两个数字对应左右、上下;四个数字对应上、右、下、左;

    HorizontalAlignment与VerticalAlignment

      在父元素中,当剩余空间很大时(超过子元素需要),这两个属性可以控制字元素的位置。比如,在垂直排列的StackPanel中,面板宽度默认和最宽的元素宽度相同,其他控件的宽度默认将会被拉伸。这时,可以使用HorizontalAlignment属性来控制,默认值为Stretch(拉伸),还有Left、Center、Right。VerticalAlignment则有Stretch、Top、Center和Bottom四个枚举值。   

    Visibility可见度,决定元素是否可见。枚举值有两个:Collapsed和Hidden。Collapsed元素不可见,并且首选尺寸变为0,不再影响布局。Hidden元素虽然不可见,但尺寸不变,布局系统仍按可见的处理。

    FlowDirection文本方向,默认情况下基于系统的本地设置。比如英语、中文都是从左往右排列,LeftToRight;希伯来文从右往左排列,RightToLeft。如果为面板指定该属性,则面板的所有子元素都按此方向排列。

    Panel.ZIndex,Panel定义的一个附加属性ZIndex,用于多个元素重叠时,指定显示的上下层关系。ZIndex值大的将出现在值小的元素上方。元素显示顺序将不受文档定义顺序控制。如果不使用ZIndex,重叠元素将根据文档定义的顺序显示,后定义的元素出现在上方。

    Binding基础

    首先,创建一个类Student,继承INotifyPropertyChanged。定义几个字段以及一个组件属性更改引发的方法。贴代码:

    复制代码
    public class Student:INotifyPropertyChanged 
        {
            private string name;
            public string Name
            {
                get
                {
                    return name;
                }
                set
                {
                    this.name = value;
                    NotifyPropertyChanged("Name");
                }
            }
    
            private int id;
            public int ID
            {
                get
                {
                    return id;
                }
                set
                {
                    this.id = value;
                    NotifyPropertyChanged("ID");
                }
            }
    
            public int age;
            public int Age
            {
                get
                {
                    return age;
                }
                set
                {
                    this.age = value;
                    NotifyPropertyChanged("Age");
                }
            }
    
            public event PropertyChangedEventHandler PropertyChanged;
            private void NotifyPropertyChanged(string propertyName)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
            }
        }
    复制代码

    1、在前台wpf界面定义一个button控件(btnBinding_Click),用以改变Name字段的值,将控件textbox(tbDisplay)绑定到Name字段。基本步骤:

    (1)所有代码都写在后台逻辑:

    准备数据源:Student student = new Student();

    准备Binding:

    Binding binding = new Binding();                    

    binding.Source = student;                    

     binding.Path = new PropertyPath("Name");

    使用Binding连接到数据源与Binding目标:BindingOperations.SetBinding(this.tbDisplay, TextBox.TextProperty, binding);

    将上述三步操作合一:this.tbDisplay.SetBinding(TextBox.TextProperty, new Binding("Name") { Source = student = new Student() });

    (2)不过大家一般的做法是在前台界面进行绑定,同时在后台逻辑上指定绑定源,如下:

    前台绑定:<TextBox Height="23" HorizontalAlignment="Left" Margin="27,12,0,0" Name="tbDisplay" Text="{Binding Path=Name}" VerticalAlignment="Top" Width="120"  />

    后台逻辑:

    Binding bind = new Binding("Name") { Source = student };               

    this.tbDisplay.SetBinding(TextBox.TextProperty, bind);

    (3)现在将其放在一个容器内进行绑定:

    前台绑定:<StackPanel Height="226" HorizontalAlignment="Left" Margin="790,36,0,0" Name="SP" VerticalAlignment="Top" Width="239" >              

    <TextBox x:Name="tbDisplay" Width="171" Height="47" Margin="5,100,10,100" Text="{Binding Path=Name}" />              

    </StackPanel >

    后台逻辑:Student student = new Student();            

    this.SP.DataContext = student;

    2、将控件作为binding源于binding标记扩展

    所有操作都放在在前台界面中:

    <TextBox Height="23" HorizontalAlignment="Left" Margin="27,170,0,0" Name="tbNum" Text="{Binding Path=Value,ElementName=slider1}" VerticalAlignment="Top" Width="120" />                                        

    <Slider Height="23" HorizontalAlignment="Left" Margin="27,210,0,0" Name="slider1" VerticalAlignment="Top" Maximum="100" Minimum="0" Width="187" />

    3、使用集合对象作为列表控件的ItemsSource

    下面这个例子是要把List<Student>集合的实例作为ListBox的ItemsSource,同时让ListBox显示Student的Name并使用TextBox显示当前选中的条目的ID。

    前台界面:

    <TextBox Height="23" HorizontalAlignment="Right" Margin="0,52,571,0" Name="tbID" VerticalAlignment="Top" Width="120" />              

    <ListBox Height="100" HorizontalAlignment="Left" Margin="414,162,0,0" Name="lbStudent" VerticalAlignment="Top" Width="120" />

    后台的逻辑:

    复制代码
    List<Student> stuList = new List<Student>()
                {
                    new Student (){ID=0,Name="Tim",Age=23},
                    new Student (){ID=1,Name="Tom",Age=24},
                    new Student (){ID=2,Name="Mike",Age=25},
                };
    
                //为listbox设置Binding
                this.lbStudent.ItemsSource = stuList;
                this.lbStudent.DisplayMemberPath = "Name";
    
    
                //为textbox设置Binding
                Binding binding = new Binding("SelectedItem.ID") { Source = this.lbStudent };
                this.tbID.SetBinding(TextBox.TextProperty, binding);
    复制代码

      

    都是一些基础,谨供学习。

    原文:http://www.cnblogs.com/ysyn/p/3408201.html

  • 相关阅读:
    vs2008 当前上下文不存在名称xxx 解决办法
    SQL Server 2008故障转移集群+数据库镜像配置实例之一
    通过JavaScript获取页面大小
    使用JavaScript判断浏览器类型
    sql2008安装图解sql2008安装全过程
    Sqlserver中对时间类型的字段转换
    SQL Server 2008故障转移集群+数据库镜像配置实例之三
    这年头口罩都成时尚品
    一位软件工程师的6年总结[转]
    MS SQL Server查询优化方法[转]
  • 原文地址:https://www.cnblogs.com/lsgsanxiao/p/5918852.html
Copyright © 2020-2023  润新知