这一章全部讲解绑定.估计还有一章基础知识就讲解完了,后面的可能我就不更新了,都是用工具生成一些数据绑定,2d,3d的效果.我贴上1000多行代码,给大家看看效果没什么意思.

<?xml version="1.0" encoding="utf-8" ?>

<Persons xmlns="">

  <person Name="Person1">

    <ID>1</ID>

    <Name>张三丰</Name>

    <Age>49</Age>

  </person>

  <person Name="Person2">

    <ID>2</ID>

    <Name>阿贵</Name>

    <Age>29</Age>

  </person>

  <person Name="Person3">

    <ID>3</ID>

    <Name>陈世美</Name>

    <Age>103</Age>

  </person>

  <person Name="Person4">

    <ID>4</ID>

    <Name>李小龙</Name>

    <Age>59</Age>

  </person>

</Persons>

一个xml文件.用于数据绑定

<Window x:Class="WPFBindXML.Window1"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    Title="Window1" Height="334" Width="496">

    <Grid>

 

        <ListView Margin="12,12,12,121" Name="listView1" SelectionChanged="listView1_SelectionChanged">

            <ListView.View>

                <GridView>

                    <GridViewColumn Header="编号" DisplayMemberBinding="{Binding XPath=ID}"  Width="100" />

                    <GridViewColumn Header="姓名" DisplayMemberBinding="{Binding XPath=Name}" Width="100"/>

                    <GridViewColumn Header="年龄" DisplayMemberBinding="{Binding XPath=Age}" Width="100">

                    </GridViewColumn>

                </GridView>

            </ListView.View>

        </ListView>

        <Label Height="25" Margin="12,0,12,90" Name="label1" VerticalAlignment="Bottom"></Label>

        <Button Height="22" Margin="20,0,124,45" Name="button1" VerticalAlignment="Bottom" Click="button1_Click">将XML 文件绑定到元素</Button>

        <Button Height="27" Margin="20,0,124,12" Name="button2" VerticalAlignment="Bottom" Click="button2_Click">将 自定义对象绑定到元素</Button>

<ComboBox Name="com1" Height="20" Width="200" />

 

    </Grid>

</Window>

下面是后台绑定代码

namespace WPFBindXML

{

    public partial class Window1 : Window

    {

        public Window1()

        {

            InitializeComponent();

        }

        private void button1_Click(object sender, RoutedEventArgs e)

        {

//让一个listview绑定一个xml文件.

            XmlDocument doc = new XmlDocument();

            doc.Load(@"..\..\XMLFile1.xml");

//直接访问xml数据

            XmlDataProvider provider = new XmlDataProvider();

            provider.Document = doc; //绑定到一个xml对象

            provider.XPath = @"/Persons/person"; //xpath查询

            listView1.DataContext = provider;//listview的数据源指向

            listView1.SetBinding(ListView.ItemsSourceProperty, new Binding());//绑定

        }

        private void listView1_SelectionChanged(object sender, SelectionChangedEventArgs e)

        {

            if (e.AddedItems.Count != 0)

            {

                XmlElement a = (XmlElement)e.AddedItems[0];

                this.label1.Content = a.InnerXml;//这个是你选择某一项 把值拿出来

            }

        }

        private void button2_Click(object sender, RoutedEventArgs e)

        {

            //Pesrsion P = new Pesrsion("1", "CHK76REN", "20");

            //Binding myBinding = new Binding("Name");

            //myBinding.Source = P;

            //label1.SetBinding(Label.ContentProperty, myBinding);

//banding一个自定义的数据源

 

当然 我们还可以去绑定一个下拉框的选项值

List<Pesrsion> pes = new List<Pesrsion>();

            pes.Add(new Pesrsion() { ID = "1", Name = "1", Age = "1" });

            pes.Add(new Pesrsion() { ID = "1", Name = "2", Age = "1" });

            pes.Add(new Pesrsion() { ID = "1", Name = "3", Age = "1" });

            pes.Add(new Pesrsion() { ID = "1", Name = "4", Age = "1" });

            com1.ItemsSource = pes;

            com1.DisplayMemberPath = "Name";

 

        }

    }

    public class Pesrsion

    {

        public Pesrsion(string id, string name, string age)

        {

            this.ID = id;

            this.Name = name;

            this.Age = age;

        }

        public string ID { get; set; }

        public string Age { get; set; }

        public string Name { get; set; }

    }

}

我们已经了解了绑定xml文件,绑定自定义的对象,以及对象集合.

下面我们来看一个比较复杂的例子,banding自定义模板

<Window x:Class="WPF_自定义对象绑定.Window1"

  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

  xmlns:local="clr-namespace:WPF_自定义对象绑定"

  SizeToContent="WidthAndHeight"

  Title="WPF_自定义对象绑定" Background="#FF00CCCC">

//这个资源里面 我们又学习了新东西 就是自定义模板  这个也可以放在资源里面的

    <Window.Resources>

         <DataTemplate x:Key="UserDataTemp">

            <Border Name="border" BorderBrush="Aqua" BorderThickness="1"

              Padding="5" Margin="5">

                <Grid>

                    <Grid.RowDefinitions>

                        <RowDefinition/>

                        <RowDefinition/>

                        <RowDefinition/>

                        <RowDefinition/>

                        <RowDefinition/>

                    </Grid.RowDefinitions>

                    <Grid.ColumnDefinitions>

                        <ColumnDefinition />

                        <ColumnDefinition />

                    </Grid.ColumnDefinitions>

                    <TextBlock Grid.Row="0" Grid.Column="0" Text="ID:"/>

                    <TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding Path=Id}" />

                    <TextBlock Grid.Row="1" Grid.Column="0" Text="Name:"/>

                    <TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding Path=Name}"/>

                    <TextBlock Grid.Row="2" Grid.Column="0" Text="Address:"/>

                    <TextBlock Grid.Row="2" Grid.Column="1" Text="{Binding Path=Address}"/>

                    <TextBlock Grid.Row="3" Grid.Column="0" Text="UserName:"/>

                    <TextBlock Grid.Row="3" Grid.Column="1" Text="{Binding Path=UserName}"/>

                    <TextBlock Grid.Row="4" Grid.Column="0" Text="PassWord:"/>

                    <TextBlock Grid.Row="4" Grid.Column="1" Text="{Binding Path=PassWord}"/>

                </Grid>

            </Border>

        </DataTemplate>

    </Window.Resources>

    <StackPanel>

        <Label Content="WPF_自定义对象绑定" Height="73" Name="label1" FontSize="24" Width="426" />

        <TextBlock Margin="10,0,0,0">选择项</TextBlock>      

        <ListBox SelectionChanged="ListBox_SelectionChanged"

                 SelectedIndex="0" Margin="10,0,10,0" >

            <ListBoxItem>第一条</ListBoxItem>

            <ListBoxItem>第二条</ListBoxItem>

            <ListBoxItem>第三条</ListBoxItem>

        </ListBox>    

//让listbox去指定一个自定义的模板

        <ListBox Width="400" Margin="10" Name="myListBox"

                 HorizontalContentAlignment="Stretch"

                 ItemsSource="{Binding}"

                 ItemTemplate="{StaticResource UserDataTemp}"/>

    </StackPanel>

</Window>

//后台绑定的代码

namespace WPF_自定义对象绑定

{

    public partial class Window1 : Window

    {

        Users users = new Users();//初始化数据

        public Window1()

        {

            InitializeComponent();

            users.Add(new User(1, "asdf", "北京市东城区", "chk", "1111"));

            users.Add(new User(2, "王三", "北京市朝阳区", "sss", "234"));

            users.Add(new User(3, "刘金金", "北京市朝阳区", "ppp", "888"));

            users.Add(new User(4, "程晓春", "北京市海淀区", "ppp", "888"));

        }

        private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)

        {

            int id = (sender as ListBox).SelectedIndex + 1;

            this.DataContext = from u in users where u.Id == id select u;

        }

    }

}

下面是自定义的对象代码

using System.ComponentModel;

using System.Collections.ObjectModel;

 

namespace WPF_自定义对象绑定

{

//向客户端发出某一属性值已更改的通知, InotifyPropertyChanged这个接口的含义

    public class User : INotifyPropertyChanged

    {

        private int id;

        private string name;

        private string address;

        private string username;

        private string password;

        public event PropertyChangedEventHandler PropertyChanged;

        public User()

        {

        }

        public User(int id, string name, string address, string username, string password)

        {

            this.id = id;

            this.name = name;

            this.address = address;

            this.username = username;

            this.password = password;

        }

        public override string ToString()

        {

            return name.ToString();

        }

        public int Id

        {

            get { return id; }

            set

            {

                id = value;

                OnPropertyChanged("Id");//有更改就触发这个事件

            }

        }

        public string Name

        {

            get { return name; }

            set

            {

                name = value;

                OnPropertyChanged("Name");

            }

        }

        public string Address

        {

            get { return address; }

            set

            {

                address = value;

                OnPropertyChanged("Address");

            }

        }

        public string UserName

        {

            get { return username; }

            set

            {

                username = value;

                OnPropertyChanged("UserName");

            }

        }

        public string PassWord

        {

            get { return password; }

            set

            {

                password = value;

                OnPropertyChanged("PassWord");

            }

        }

        protected void OnPropertyChanged(string info)

        {

            PropertyChangedEventHandler handler = PropertyChanged;

            if (handler != null)

            {

                handler(this, new PropertyChangedEventArgs(info));

            }

        }

}

//这个类 和List<User>相等..

    public class Users : ObservableCollection<User>

    {

        public Users()

            : base()

        { }

    }

}

忘了告诉大家怎么绑定dataTable了,不过我相信大家也是会的,不会的可以看看下面的代码.

CREATE TABLE [dbo].[Table_1](  [Id] [nvarchar](50) NULL,  [Name] [nvarchar](50) NULL ) 创建一个最简单的表,就两个字段

<Window x:Class="WPFBindXML.Window2"         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"         Title="Window2" Height="334" Width="496">    

<Grid>        

<ListView Margin="12,12,12,121" Name="listView1">            

<ListView.View>                

<GridView>                    

<GridViewColumn Header="编号" DisplayMemberBinding="{Binding Path=Id}" Width="100" />                    

<GridViewColumn Header="姓名" DisplayMemberBinding="{Binding Path=Name}" Width="100" />                

 </GridView>            

</ListView.View>        

</ListView>    

</Grid>

</Window>

代码比较乱,大家复制过去看看就行了.

namespace WPFBindXML

{   

     public partial class Window2 : Window    

{        

 public Window2()        

 {            

InitializeComponent();     

        string conStr = "server=.;uid=sa;pwd=1;database=ZuoYe";  

           SqlConnection con = new SqlConnection(conStr);    

         string sql = "select * from Table_1";  

           SqlCommand cmd = new SqlCommand(sql, con);   

          SqlDataAdapter adapter = new SqlDataAdapter(cmd);  

           DataSet ds = new DataSet();

            adapter.Fill(ds);      

       this.listView1.DataContext = ds.Tables[0].DefaultView;   

          listView1.SetBinding(ListView.ItemsSourceProperty, new Binding());   

      }  

   }

 }

代码比较简单,不说了,我就是随便写了几行代码,测试用的.

posted @ 2012-01-30 12:08 crud 阅读(326) 评论(2) 编辑

先来了解一下什么是依赖属性,先来看看这段代码,大家很熟悉,但是为什么我要让大家看呢.

<Window x:Class="WPF依赖属性.Window1"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

Title="Window1" Height="332" Width="501" Background="Tomato">

//这是一个静态资源,大家很熟悉

    <Window.Resources>

        <SolidColorBrush x:Key="MyBrush" Color="Gold"/>

    </Window.Resources>

    <Grid>

        <Grid.ColumnDefinitions>

            <ColumnDefinition Width="72*" />

            <ColumnDefinition Width="206*" />

        </Grid.ColumnDefinitions>

//这里使用了静态资源,为什么他能认识上面的值呢,就是因为wpf的依赖属性机制实现的.

        <Button Background= "{StaticResource  MyBrush}" Content="1 使用依赖属性从资源动态获取参数" Height="47" VerticalAlignment="Top" Margin="38,62,30,0" Grid.ColumnSpan="2" />

        <Button Margin="38,115,30,124" Name="button1" Click="button1_Click" Grid.ColumnSpan="2">2 Get 依赖属性</Button>

        <TextBox Margin="38,0,120,16" Name="textBox1" Height="23" VerticalAlignment="Bottom" Grid.ColumnSpan="2">你好</TextBox>

        <Button Margin="38,0,30,86" Name="button2" Click="button2_Click" Grid.ColumnSpan="2" Height="23" VerticalAlignment="Bottom">3 Set 依赖属性</Button>

        <Button Height="23" Margin="38,0,30,45" Name="button3" VerticalAlignment="Bottom" Click="button3_Click" Grid.ColumnSpan="2">4 使用属性封装依赖属性</Button>

        <Label Height="45" Margin="105,11,90,0" Name="label1" VerticalAlignment="Top" FontSize="24" Grid.ColumnSpan="2">依赖属性演示  </Label>

    </Grid>

</Window>

依赖属性的我们使用了很多次的资源字典的形式来写,今天我们换一种方法使用.这个是后台代码我们一点点看.

namespace WPF依赖属性

{

    /// <summary>

    /// Window1.xaml 的交互逻辑

    /// </summary>

    public partial class Window1 : Window

    {

        public Window1()

        {

            InitializeComponent();          

        }

//依赖属性今天要说的就是这些东西. 这行代码表示向wpf属性系统注册依赖属性

//前三个参数,很简单,然后就是注册的值,后面跟着一个值发生改变的回调.

        private static readonly DependencyProperty myNameProperty = DependencyProperty.Register(

          "myName",

          typeof(string),

          typeof(Window1),

          new FrameworkPropertyMetadata(".NET Hello",

          FrameworkPropertyMetadataOptions.AffectsRender,

          new PropertyChangedCallback(OnMyNamePropertyChanged)

  )

);

//封装了注册的实例,便于访问.

        public string MyNameProperty

        {

            get { return this.GetValue(Window1.myNameProperty).ToString(); }

            set { SetValue(Window1.myNameProperty, value); }

        }

//这是一个回调,只要注册的值发生了改变,就会弹出这个对话框.

        public static void OnMyNamePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)

        {

            global::System.Windows.MessageBox.Show("值发生改变了...");

        }

//通过GetValue的方式拿到注册的依赖属性值

        private void button1_Click(object sender, RoutedEventArgs e)

        {

            global::System.Windows.MessageBox.Show(this.GetValue(Window1.myNameProperty).ToString());

        }

//使用SetValue对注册的依赖属性进行更改,这时候上面那个回调就会起作用了

        private void button2_Click(object sender, RoutedEventArgs e)

        {

            this.SetValue(Window1.myNameProperty, this.textBox1.Text);

                      //this.MyNameProperty = this.textBox1.Text;  //get set的使用,不说了

        }

//通过封装的属性,来访问注册的依赖属性

        private void button3_Click(object sender, RoutedEventArgs e)

        {

            global::System.Windows.MessageBox.Show(this.MyNameProperty);

        }

    }

}

下面继续了解路由事件.先看一下wpf的事件的几种工作方式.

直接方式,只有元素自身调用的事件

冒泡方式,从根元素向根节点依次响应事件

隧道方式,从根节点向根元素依次响应事件

先来看一段隧道方式的事件代码,在wpf里面所有PreviewMouseDown这种P开头的事件都是隧道事件.

<Window x:Class="绑定依赖属性路由.MainWindow"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        Title="MainWindow" Height="350" Width="525">

    <Grid PreviewMouseDown="Grid_PreviewMouseDown">

        <Button Content="Button1" Height="23" HorizontalAlignment="Left" Margin="12,12,0,0" Name="button1" VerticalAlignment="Top" PreviewMouseDown="button1_PreviewMouseDown" Width="75" />

    </Grid>

</Window>

 

前台就一个button按钮,grid和button都在使用同一种事件,看谁先响应.

private void Grid_PreviewMouseDown(object sender, MouseButtonEventArgs e)

        {

            MessageBox.Show("Grid1");

            //e.Handled = true; 这句话的意思是  截断事件,如果截断了事件,就不会响应button的事件了.

        }

        private void button1_PreviewMouseDown(object sender, MouseButtonEventArgs e)

        {

            MessageBox.Show("button1");

        }

后台就两个事件代码.其他的工作方式都是和以前一样,大家试试就知道了,只有隧道模式比较特殊.

Wpf里面还可以通过这样来添加事件.新的特性.

这是一个button的点击事件,很正常.

private void Button_Click3(object sender, RoutedEventArgs e) {

我们可以通过找到这个元素的name来添加事件. Grid.MouseDownEvent 这样就是为这个元素添加一个MouseDown事件.

            grid3.AddHandler(Grid.MouseDownEvent, new RoutedEventHandler(Grid_MouseDownNext), true);

                   }

        private void Grid_MouseDownNext(object sender, RoutedEventArgs e) {

            MessageBox.Show("Grid被点击");

  }

下面来了解一个比较麻烦的例子,依赖事件.

前台代码比较简单就是一个button按钮

 <Window x:Class="WPF_依赖事件.Window1"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    Title="Window1" Height="300" Width="300" Loaded="Window_Loaded">

  

 <Grid>

        <Label Height="47" Margin="12,12,-7,0" Name="label1" VerticalAlignment="Top" FontSize="24">依赖事件演示</Label>

        <Button Height="23" Margin="59,0,21,64" Name="button1" VerticalAlignment="Bottom" >Send</Button>

    </Grid>

</Window>

后台代码比较麻烦

namespace WPF_依赖事件

{

    /// <summary>

    /// Window1.xaml 的交互逻辑

    /// </summary>

    public partial class Window1 : Window

    {

        public Window1()

        {

            InitializeComponent();

..通过这种方式来添加一个路由

            this.button1.AddHandler(Button.ClickEvent, new RoutedEventHandler(C));

当然,还可以这样写

            //this.button1.Click += new RoutedEventHandler(button1_Click); 直接+=

            //this.button1.Click += (senders, es) => { }; 通过lambda

            //this.button1.Click += delegate { }; 匿名方法

//这个事件比较是 自定义的一个事件

            this.okRoutedEvent += new RoutedEventHandler(Window1_okRoutedEvent);

        }

 

        void Window1_okRoutedEvent(object sender, RoutedEventArgs e)

        {

            global::System.Windows.MessageBox.Show(DateTime.Now.ToString());

        }

//一个静态的只读性的事件字段

        private static readonly RoutedEvent okEvent = EventManager.RegisterRoutedEvent("okEvent", RoutingStrategy.Direct, typeof(RoutedEvent), typeof(RoutedEventArgs));

//我们通过一种事件属性的写法 来访问这个事件

        public event RoutedEventHandler okRoutedEvent

        {

            add

            {

                AddHandler(okEvent, value);

            }

            remove

            {

RemoveHandler(okEvent, value);

            }

        }

//这个是button点击的事件

        public void C(object o, RoutedEventArgs e)

        {

//通过button点击来发布这个事件.

            RoutedEventArgs args = new RoutedEventArgs(okEvent);

            this.RaiseEvent(args);        //引发特定的路由事件   

        }

        private void Window_Loaded(object sender, RoutedEventArgs e)

        {

 

        }

    }

}

//总结来说,就是用 定义了一个路由事件.通过事件属性来访问, 让当前窗体使用这个事件, 然后通过 button的点击来发布这个事件,达到触发窗体 自定义的事件,非常好理解的一个逻辑.

下章全部讲解数据绑定.

posted @ 2012-01-30 11:08 crud 阅读(289) 评论(0) 编辑

继续学习wpf的系列课程.

首先我们看一下后台代码访问前台的UI控件.

这块的知识比较老套,不管我们开发cs,bs都一直在使用的.在讲着系列课程的时候,我以及把所以的代码,要要讲的内容都写了一遍,发博客只是改动一些东西.

<Window x:Class="WPFUserPanel.Window1"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    Title="后天获取XAML 元素" Height="395" Width="395" BorderThickness="5" FlowDirection="LeftToRight" Grid.IsSharedSizeScope="False" ShowActivated="False" Background="BlanchedAlmond">

    <Window.Resources >

  </Window.Resources>

    <Grid>

        <Grid.RowDefinitions>

            <RowDefinition />

            <RowDefinition />

        </Grid.RowDefinitions>

        <Grid.ColumnDefinitions>

            <ColumnDefinition Width="121*" />

            <ColumnDefinition Width="123*" />

            <ColumnDefinition Width="119*" />

        </Grid.ColumnDefinitions>

        <TextBox Grid.ColumnSpan="3" Margin="27,47,31,78" Name="textBox1" FontSize="24">Hello  WPF 太神奇了</TextBox>

        <Button Grid.Row="1" Height="48" Margin="105,0,108,0" Name="button1" VerticalAlignment="Top" Click="button1_Click" Background="SandyBrown" BorderThickness="1" FontSize="18" Grid.ColumnSpan="3">第一种方式</Button>

        <Button Margin="105,54,108,76" Name="button2" Grid.Row="1" Click="button2_Click" Background="SandyBrown" BorderThickness="1" FontSize="18" Grid.ColumnSpan="3">第二种方式</Button>

        <Button Margin="105,0,108,28" Name="button3" Grid.Row="1" Click="button3_Click" Background="SandyBrown" BorderThickness="1" FontSize="18" Grid.ColumnSpan="3" Height="42" VerticalAlignment="Bottom">第三种方式</Button>

    </Grid>

</Window>

前台的xaml代码,没什么好说的.

后台代码的几种访问方式.

namespace WPFUserPanel {

    public partial class Window1 : Window {

        public Window1() {

            InitializeComponent();

        }

        void B_SizeChanged(object sender, SizeChangedEventArgs e) {

            throw new NotImplementedException();

  }

 

        private void button1_Click(object sender, RoutedEventArgs e) {

//第一种访问的方式,刚我们可以用GetValue的方式来访问,当然你直接textBox1.Text是最简单的

            System.Windows.MessageBox.Show("" + this.textBox1.GetValue(TextBox.TextProperty).ToString());

        }

 

        private void button2_Click(object sender, RoutedEventArgs e) {

//这个类似于开发bs的FindControl一样,来查找我们需要的控件

            TextBox t = this.FindName("textBox1") as TextBox;

            System.Windows.MessageBox.Show("第二种方式:" + t.Text);

        }

 

        private void button3_Click(object sender, RoutedEventArgs e) {

//这种比较麻烦, 我们先找到内容

            var v = this.Content;

//转为grid布局控件,然后把控件全部拷贝到控件数组

            Grid g = v as Grid;

            UIElementCollection uc = g.Children;

            Control[] us = new Control[uc.Count];

            g.Children.CopyTo(us, 0);

//用linq来查找这个控件. 相信大家能看懂简单的linq, 我的linq水平也是半吊子.. 一直都是在用linqToObjects,别的也没看,看20分钟 就能简单使用了.

            string str = (us.First (a => a.Name == "textBox1") as TextBox).Text;

            System.Windows.MessageBox.Show("第三种方式:" + str);

        }

    }

}

我们接着玩一个纯cs文件的wpf程序,相信大家做cs的时候,经常这样玩,我以前就是,不用窗体,只用代码来写cs程序.

我们来创建一个wpf应用程序,把所有的东西全部删掉.ok,我们把下面的代码添加进去

 

namespace WPFLayoutDemo

{

    class subMain : System.Windows.Application

    {

        [STAThread]//指定com的线程模型是单线程基元

        public static void Main()

        {

 

            System.Windows.Application app = new Application();

            MyWindow mw = new MyWindow();

            mw.Width = 400;

  mw.Height = 400;

            mw.BorderThickness = new Thickness(50, 5, 50, 5);

            app.Run(mw);//启动应用程序

        }

    }

 

    public partial class MyWindow : Window

    {

        Canvas canv;

        Ellipse e1;

        Button b1;

        Label lab1;

        Rectangle r1;

        public MyWindow()

        {

            canv = new Canvas();

            canv.Name = "C1";

            this.Content = canv;//让当前的对象等于canvas

            canv.Margin = new Thickness(0, 0, 0, 0);

            canv.Background = new SolidColorBrush(Colors.White);

 

            e1 = new Ellipse();

            e1.Fill = new SolidColorBrush(Colors.YellowGreen);

            e1.Stroke = new SolidColorBrush(Colors.Azure);

            e1.Width = 200;

            e1.Height = 200;

            e1.Margin = new Thickness(50, 100, 0, 0);

            canv.Children.Add(e1);//让canvas的实例去添加一个元素

 

 

            r1 = new Rectangle();

            r1.Fill = new SolidColorBrush(Colors.Tomato);

            r1.Opacity = 0.5;

            r1.Stroke = new SolidColorBrush(Colors.Red);

            r1.Width = 200;

            r1.Height = 200;

 

            r1.SetValue(Canvas.LeftProperty, (double)150);

            r1.SetValue(Canvas.TopProperty, (double)100);

            canv.Children.Add(r1);

 

 

            b1 = new Button();

            b1.Width = 100;

  b1.Height = 20;

            b1.Content = "修改圆形位置";

            b1.SetValue(Canvas.LeftProperty, (double)r1.GetValue(Canvas.LeftProperty) + 50);

            b1.SetValue(Canvas.TopProperty, (double)r1.GetValue(Canvas.TopProperty) + 50);

            b1.Click += new RoutedEventHandler(b1_Click);

            canv.Children.Add(b1);

 

 

            Label lab0 = new Label();

            lab0.Margin = new Thickness(20, 20, 0, 0);

            lab0.Width = 400;

            lab0.Height = 40;

            lab0.FontSize = 24;

            lab0.Name = "lab0";

            lab0.Content = "无XAML动态编程演示   作者:常鲲";

            canv.Children.Add(lab0);

 

            lab1 = new Label();

            lab1.Margin = new Thickness(20, 50, 0, 0);

            lab1.Width = 400;

            lab1.Height = 40;

            lab1.FontSize = 24;

            lab1.Name = "lab1";

            lab1.Content = "Location:?";

            canv.Children.Add(lab1);

//这个是Ellipse的实例对象的MouseMove事件.

            e1.MouseMove += new System.Windows.Input.MouseEventHandler(el_MouseMove);

        }

 

        void b1_Click(object sender, RoutedEventArgs e)

        {

            Point p = System.Windows.Input.Mouse.GetPosition(canv as System.Windows.IInputElement);

         //重新设置Ellipse的位置,前面讲过两种的设置方法.

            e1.Margin = new Thickness(p.X, p.Y, 0, 0);

        }

 

 

        void el_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)

        {

            Ellipse a = e.Source as Ellipse;

//获得当前鼠标的位置,这个是wpf重新封装的一个类库用System.Windows.Input.Mouse来获得鼠标的各种状态.

            Point p = System.Windows.Input.Mouse.GetPosition(canv as

System.Windows.IInputElement);

            lab1.Content = "Location:" + p.ToString();//

        }

    }

}

总体来说,这个小技术,控件查找,动态窗体,以后会用的很多.也比较简单,好理解.

下面我们来学习样式,样式其实和bs的样式表类似,只是写法不同而已.

先来看一下xaml代码.

<Window x:Class="WPF_资源和样式.Window1"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    Title="Window1" Height="400" Width="400" Loaded="Window_Loaded">

 

<Window.Resources >//这里我定义了静态资源

// TargetType="{x:Type Button}" 注意这句话 这是为Button设置的样式,别的控件不能使用

        <Style x:Key="GreenButtonStyle" TargetType="{x:Type Button}">

//属性样式都是以Setter开头的

            <Setter Property="Control.Width" Value="350"/>

            <Setter Property="Control.Height" Value="100"/>

            <Setter Property="Control.FontSize" Value="24"/>

//事件样式都是以EventSetter开头的  Event是指那种类型的事件 Handler是指向后台的一个方法

            <EventSetter Handler="Button_Click" Event="Click"></EventSetter>

        </Style>

        <SolidColorBrush x:Key="backgroundBrush">Yellow</SolidColorBrush>

        <SolidColorBrush x:Key="borderBrush">Red</SolidColorBrush>

    </Window.Resources>

<Grid  Background="{StaticResource borderBrush}">

//我们只需要用style来指定一下静态资源就可以了

        <Button Style="{StaticResource GreenButtonStyle}" Background="{ StaticResource backgroundBrush}">WPF 资源和样式的应用</Button>

        <Label Height="53" Margin="31,27,41,0" Name="label1" VerticalAlignment="Top" FontSize="24">WPF 中资源和样式的应用</Label>

//这个button使用的是动态资源,后面就是这个资源的代码

        <Button Content="这是通过字典项设置的样式" Margin="17,0,17,73.163" Style="{DynamicResource GreyButton}" VerticalAlignment="Bottom" Height="35.837"  />

    </Grid>

</Window>

//资源字典的代码

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <Style x:Key="GreyButton" TargetType="Button" >

        <Setter Property="Background" Value="#00FFFF"/>

    </Style>

</ResourceDictionary>

//后台的代码

  private void Button_Click(object sender, RoutedEventArgs e)

        {

            global::System.Windows.MessageBox.Show("WPF 的 XAML 确实强大!");

        }

我们后台只有一个button的click的事件,总体来说,样式只是写法不同,并没有多少技术难度.

这章我们先认识一些比较麻烦的东西,下章开始讲解.

依赖属性,路由事件,binding,和命令,把这些讲解完毕后,wpf的基础部分就告一段落,剩下的年后再说.

posted @ 2012-01-17 11:06 crud 阅读(221) 评论(0) 编辑

继续沿用前两章的讲法,只讲用法,概念,到这一系列课程更新完毕,我会找一些例子讲解一些技术难点. 回顾前两章,我们学习了导航,线程,xaml等一些wpf的技术,这章的技术我不是很擅长,关于布局,我找了一本书,把一些重点和大家说说…

 

先介绍几种布局的结构,

1 , Border 只能包含一个元素,用于生成边框

2, grid 这个布局非常常用,采用了非常灵活的行和列,(构成网格)来排序子元素

3, canvas 按照x和y绝对坐标来排序子元素.

4, stackPanel 将子元素沿水平或垂直方向排列(或 堆叠 )成一行

5, DockPanel 将子元素沿水平或垂直方向排列(或 堆叠 )成一行

6, ScrollViewer  一个允许您滚动其中所含的子元素的元素。该元素仅包含单个子元素

7, WrapPanel 按从左至右的顺序连续排列子元素,等排到面板的最右侧后,将内容 环绕 到下一行,从而形成从左至右、从上至下的排列方式

8, UniformGrid 在相等或均匀的网格区域中排列子元素

9, Viewbox 缩放其所有子元素,与缩放控件非常相似

下面复制一些代码 大家粘贴过去看看就行了,比较如果真干wpf,我们也多是写后台代码,了解前台布局,能看懂就行了.

<Grid x:Name="LayoutRoot">

                   <Grid.RowDefinitions>

                            <RowDefinition Height="0.33*"/>

                            <RowDefinition Height="0.33*"/>

                            <RowDefinition Height="0.33*"/>

                   </Grid.RowDefinitions>

                   <Grid.ColumnDefinitions>

                            <ColumnDefinition Width="0.33*"/>

                            <ColumnDefinition Width="0.33*"/>

                            <ColumnDefinition Width="0.33*"/>

                   </Grid.ColumnDefinitions>

                   <Border BorderBrush="#FFF1621E" BorderThickness="20,10" Margin="8" CornerRadius="20">

                            <Border.Background>

                                     <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">

                                               <GradientStop Color="#FFECFFDF" Offset="0.75"/>

                                               <GradientStop Color="#FFC0FF96" Offset="1"/>

                                     </LinearGradientBrush>

                            </Border.Background>

                            <TextBlock Margin="6,7,8,7" TextWrapping="Wrap" Text=" Border 只能包含一个子元素,用于生成边框"/>

                   </Border>

                   <Grid Grid.Column="1" Margin="8,8,0,8">

                            <Grid.Background>

                                     <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">

<GradientStop Color="#FF95D241" Offset="0.806"/>

                                               <GradientStop Color="#FFB9F764" Offset="1"/>

                                     </LinearGradientBrush>

                            </Grid.Background>

                            <TextBlock TextWrapping="Wrap" Height="38.08" VerticalAlignment="Top"><Run Text="Grid 采用非常灵活的行和列(构成 网格 )布局来排列子元素。"/></TextBlock>

                            <Rectangle

                                     Fill="{DynamicResource StandardLinearGradientBrush}" Stroke="Black" Width="47" HorizontalAlignment="Left" Margin="8,63.08,0,42"/>

                            <Rectangle Fill="{DynamicResource StandardLinearGradientBrush}" Height="36" Margin="31.192,0,0,18.92" Stroke="Black" VerticalAlignment="Bottom" HorizontalAlignment="Left" Width="59" RadiusY="10.34" RadiusX="10.34"/>

                            <Rectangle Fill="{DynamicResource {x:Static SystemColors.InactiveCaptionBrushKey}}" Margin="70.192,0,79.952,42" Stroke="Black" RadiusY="8.42" RadiusX="8.42" Height="25" VerticalAlignment="Bottom"/>

                   </Grid>

                   <Canvas Background="{DynamicResource {x:Static SystemColors.ActiveCaptionBrushKey}}" Grid.Column="2" Margin="8" >

                            <TextBlock TextWrapping="Wrap" Text="Canvas 按照 X 和 Y 绝对坐标来排列子元素。  可用于固定元素在运行期间所在的屏幕位置,这与空白“画布” 类似。" Height="62" Width="190"/>

                            <Rectangle Fill="{DynamicResource StandardLinearGradientBrush}" Height="27" Canvas.Left="8" Stroke="Black" Canvas.Top="81" Width="49.048"/>

                            <Rectangle Fill="{DynamicResource StandardLinearGradientBrush}" Height="32" Canvas.Left="34.048" Stroke="Black" Canvas.Top="97" Width="49"/>

                            <Rectangle Fill="{DynamicResource StandardLinearGradientBrush}" Height="36.08" Canvas.Left="62.048" Stroke="Black" Canvas.Top="112.92" Width="48"/>

                   </Canvas>

                   <StackPanel Background="#FFCDE540" Margin="8,3.769,1.76,0" Grid.Row="1" >

                            <TextBlock TextWrapping="Wrap" Text="StackPanel 将子元素沿水平或垂直方向排列(或 堆叠 )成一行。" Height="46"/>

                            <Rectangle Fill="{DynamicResource StandardLinearGradientBrush}" Height="27" Stroke="Black" Width="49.048" HorizontalAlignment="Left" Margin="8,0,0,0"/>

                            <Rectangle Fill="{DynamicResource StandardLinearGradientBrush}" Height="32" Stroke="Black" Width="49" HorizontalAlignment="Left" Margin="34.048,0,0,0"/>

                            <Rectangle Fill="{DynamicResource StandardLinearGradientBrush}" Height="29.08" Stroke="Black" Margin="71.048,0,69,0"/>

                   </StackPanel>

                   <DockPanel Background="#FF63A5EB" Grid.Column="1" Margin="8,3.769,0,0" Grid.Row="1" >

                            <TextBlock TextWrapping="Wrap" Text="DockPanel 将子元素沿水平或垂直方向排列(或 堆叠 )成一行。" Width="135.048"/>

                            <Rectangle Fill="{DynamicResource StandardLinearGradientBrush}" Height="27" Stroke="Black" Width="49.048" Margin="0,0,0,10" VerticalAlignment="Bottom"

DockPanel.Dock="Bottom"/>

                            <Rectangle Fill="{DynamicResource StandardLinearGradientBrush}" Height="32" Stroke="Black" Width="49" Margin="0,0,0,10" VerticalAlignment="Bottom" DockPanel.Dock="Bottom"/>

                            <Rectangle Fill="{DynamicResource StandardLinearGradientBrush}" Height="42.08" Stroke="Black" Width="48" Margin="0,0,0,10" VerticalAlignment="Bottom" DockPanel.Dock="Bottom"/>

                   </DockPanel>

                   <ScrollViewer Background="#FF99D1AC" Grid.Column="2" Margin="8,0,8,3.769" Grid.Row="1" >

                            <Grid>

                                     <TextBlock TextWrapping="Wrap" Text="ScrollViewer  一个允许您滚动其中所含的子元素的元素。该元素仅包含单个子元素。" Height="63" VerticalAlignment="Top"/>

                                     <Rectangle Fill="{DynamicResource StandardLinearGradientBrush}" Height="27" Stroke="Black" Width="49.048" HorizontalAlignment="Left" Margin="8,0,0,40.931" VerticalAlignment="Bottom"/>

                                     <Rectangle Fill="{DynamicResource StandardLinearGradientBrush}" Height="32" Stroke="Black" Width="49" HorizontalAlignment="Left" Margin="34.048,0,0,19.931" VerticalAlignment="Bottom"/>

                                     <Rectangle Fill="{DynamicResource StandardLinearGradientBrush}" Height="28.931" Stroke="Black" Margin="51.048,0,71.096,8" VerticalAlignment="Bottom"/>

                            </Grid>

                   </ScrollViewer>

                   <WrapPanel Background="#FFD1BF99" Margin="9.76,8,0,0" Grid.Row="2" >

                            <TextBlock TextWrapping="Wrap" Text="WrapPanel 按从左至右的顺序连续排列子元素,等排到面板的最右侧后,将内容 环绕 到下一行,从而形成从左至右、从上至下的排列方式。" Height="78" Width="190.048"/>

                            <Rectangle Fill="{DynamicResource StandardLinearGradientBrush}" Height="27" Stroke="Black" Width="49.048"/>

                            <Rectangle Fill="{DynamicResource StandardLinearGradientBrush}" Height="32" Stroke="Black" Width="49"/>

                            <Rectangle Fill="{DynamicResource StandardLinearGradientBrush}" Height="42.08" Stroke="Black" Width="48"/>

                            <Rectangle Fill="{DynamicResource StandardLinearGradientBrush}" Height="24.08" Stroke="Black" Width="48"/>

                            <Rectangle Fill="{DynamicResource StandardLinearGradientBrush}" Height="33.08" Stroke="Black" Width="48"/>

                            <Rectangle Fill="{DynamicResource StandardLinearGradientBrush}" Height="42.08" Stroke="Black" Width="48"/>

                   </WrapPanel>

                   <UniformGrid Background="#FF8F99A5" Grid.Column="1" Margin="8,8,0,0" Grid.Row="2" >

                            <TextBlock TextWrapping="Wrap" Text="UniformGrid 在相等或均匀的网格区域中排列子元素。" Height="54" VerticalAlignment="Top" Margin="0,0,-1.976,0"/>

                            <Rectangle Fill="{DynamicResource StandardLinearGradientBrush}" Height="54" Stroke="Black" Margin="5.976,0,8,28.53" VerticalAlignment="Bottom"/>

                            <Rectangle Fill="{DynamicResource StandardLinearGradientBrush}" Height="64"

Stroke="Black" Margin="5.976,0,12,18.53" VerticalAlignment="Bottom"/>

                            <Rectangle Fill="{DynamicResource StandardLinearGradientBrush}" Height="64" Stroke="Black" Margin="5.976,0,8,18.53" VerticalAlignment="Bottom"/>

                   </UniformGrid>

                   <Viewbox Grid.Column="2" Margin="8,8,8,0" Grid.Row="2" Stretch="Fill" OpacityMask="Black">

                            <Grid Height="165.06" Width="206.144" Background="#FFE2AA7B">

                                     <TextBlock TextWrapping="Wrap" Text="Viewbox 缩放其所有子元素,与缩放控件非常相似。" Height="69" VerticalAlignment="Top"/>

                                     <Rectangle Fill="{DynamicResource StandardLinearGradientBrush}" Stroke="Black" Width="49.048" HorizontalAlignment="Left" Margin="8,81,0,57.06"/>

                                     <Rectangle Fill="{DynamicResource StandardLinearGradientBrush}" Height="32" Stroke="Black" Width="49" HorizontalAlignment="Left" Margin="34.048,0,0,36.06" VerticalAlignment="Bottom"/>

                                     <Rectangle Fill="{DynamicResource StandardLinearGradientBrush}" Height="42.08" Stroke="Black" Margin="71.048,0,87.096,36.06" VerticalAlignment="Bottom"/>

                            </Grid>

                   </Viewbox>

         </Grid>

代码挺多,大家拿过去看看就行了

很明显,上面我们使用的动态资源,我们先认识一下资源字典,添加一个资源字典

<ResourceDictionary

         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

         <!-- 应该在此定义资源字典条目。-->

         <SolidColorBrush x:Key="StandardSolidColorBrush" Color="White" />

         <LinearGradientBrush x:Key="StandardLinearGradientBrush" EndPoint="0.5,1" MappingMode="RelativeToBoundingBox" StartPoint="0.5,0">

                   <GradientStop Color="White"/>

                   <GradientStop Color="#FF060505" Offset="1"/>

         </LinearGradientBrush>

    <Rectangle x:Key="RX" Width="100" Height="100"></Rectangle>

</ResourceDictionary>

这个是资源字典的代码,我们上面出现很多Fill="{DynamicResource StandardLinearGradientBrush}"这样的代码,其实都差不多,这也是绑定的一种方式,动态资源,我们已经了解过了.不管动态还是静态资源,我们都是用key来描述这个资源的.

来了解一下属性面板的一些变化的东西,

Left , Top 相当于winfroms 里面的 dock属性

Width height 不用说了,Margin这个比较好理解,相当于css样式表里面的Margin –Top的这些属性. 还要关于定位,尺寸控制,停靠,等一些功能,自己看看吧.

Wpf还支持 旋转,倾斜,缩放,等功能,这个我们会在后面用eb来设计这些动画,用手写,基本累死了.(我有个朋友手写动画,现在头发快掉完了,我说的真事,骗你们不是人,呵呵)

关于旋转的几行代码.

<TextBlock Height="48.092" Margin="394,139,80,0" TextWrapping="Wrap" Text="WPF "

VerticalAlignment="Top" Foreground="#FF94EB2F" FontSize="8" TextAlignment="Center">

                            <TextBlock.RenderTransform>

                                     <TransformGroup>

                                               <ScaleTransform ScaleY="1" ScaleX="1.5"/>

                                               <SkewTransform AngleY="0" AngleX="24"/>

                                               <RotateTransform Angle="22"/>

                                               <TranslateTransform X="-23"/>

                                     </TransformGroup>

                            </TextBlock.RenderTransform>

</TextBlock>

很明显.这是一个TextBlock控件,然后任何控件都有一个转换对象RenderTransform,因为是一组转换坐标, TransformGroup,他里面包含就是转换坐标啊,一些属性的,这些基本都是用eb设计出来的.

 

下面来看一个比较有意思的例子,自定义的panel

这次我们不管xaml文件,就写后台代码

namespace WPFUserPanel

{

         //定义一个类,基础Panel, Panel是一个布局的基类

    class PlotPanel : Panel

    {

        public PlotPanel()

            : base()

        {

        }

                   //确定元素在布局中所需大小,这个方法我们没有写东西,只是更新尺寸

        protected override Size MeasureOverride(Size availableSize)

        {

            Size childSize = availableSize;

            foreach (UIElement child in InternalChildren)

            {

                child.Measure(childSize);

            }

            return availableSize;

        }

                   //为元素设置大小

        protected override Size ArrangeOverride(Size finalSize)

        {

            foreach (UIElement child in InternalChildren)

            {

                double x = 50;

                double y = 50;

                               //定位元素

                child.Arrange(new Rect(new Point(x, y), child.DesiredSize));

            }

  return finalSize;

        }

    }

}

下面是窗体的cs代码

 

namespace WPFUserPanel {

    /// <summary>

    /// Window1.xaml 的交互逻辑

    /// </summary>

    public partial class Window1 : Window {

        Button B0 = null;

        Button B1 = null;

        public Window1() {

            InitializeComponent();

                            //我们在构造函数里面 直接使用这个继承类

            PlotPanel p = new PlotPanel();

                     //设置我们的自定义panel的大小

            p.Width = 300;

            p.Height = 300;

                      //这是为背景指定一张图片,前面说过

            p.Background = new ImageBrush(new BitmapImage(new Uri("Penguins.jpg", UriKind.Relative))); ;

            this.Content = p;

 

            B0 = new Button();

            B0.Width = 200;

            B0.Height = 20;

            B0.Content = "B0 点击重新定位自定义容器";

            p.Children.Add(B0);

            B0.Click += new RoutedEventHandler(B0_Click);

 

            B1 = new Button();

            B1.Width = 200;

            B1.Height = 20;

            B1.Margin = new Thickness(0, 25, 100, 0);

            B1.Content = "B1 点击重新定位自定义容器";

            B1.Click += new RoutedEventHandler(B0_Click);

 

            p.Children.Add(B1);

        }

 

        void B0_Click(object sender, RoutedEventArgs e) {

            Button B = sender as Button;

 //这样的两句话,显示的效果完全不一样,

                      //如果就用margin来定位的话,他只是根据当前的位置进行移动

            //B.Margin = new Thickness(10, 10, 0, 0);

                            //而使用Arrange进行定位,就是重新一次定位.

            //B.Arrange(new Rect(new Point(10, 10), B.DesiredSize));

                            //这两种方法也是根据需要来用的.

        }

    }

}

这章我们讲了布局的几种用法,和动态资源,资源字典,自定义panel,下章我们继续.后面还有依赖属性,路由,绑定等一些零零碎碎的小技术..

posted @ 2012-01-17 10:56 crud 阅读(206) 评论(0) 编辑

继续wpf系列课程,本节课会讲解(xaml,)

Xaml语言,刚开始学习wpf,对xaml语言看着眼熟,其实还是有点陌生,xaml就根据xml演化而来,xaml语言的编写方式更像于asp.net网页的开发,wpf把一个窗体,分为,xaml,设计器,和cs代码,用xaml来描述窗体的样式,设计器可以直接拖拽控件,cs代码编写后台.

Xaml语法一边分为下面几种描述的方式,

1,对象元素语法,

2,特行语法 <Button Click=”button1_Click” Content=”WPF,Hello,World!” />可以这样描述一个控件

3,属性元素语法

<Button>

            <Button.Background>red</Button.Background>

</Button>

4,内容语法

<Button>hello</Button>

5,属性元素和内容合并的语法

<Button>hello

            <Button.Background>red</Button.Background>

</Button>

6,标记扩展语法

Text=”{Binding.ElementName=xxx,Path=Value}”

一般创建一个wpf的项目,xaml文件会有两部分构成,一个是window对象,一个是grid对象,

Window对象里面一般是声明了命名空间等一些定义性的东西,grid会是一个空的没有元素的布局方式.

Wpf里面也会有很多布局,数据banding等很多技术,后面都会说到.

相对应是,既然我们可以用xaml语法生成控件,那我们使用C#代码完全也可以,就像写cs程序那样,经常需要动态的添加一些控件.

Button btn = new Button();

btn.Width = 100;

btn.Height = 100;

btn.Content = "Login";

this.Content = btn;

这几行代码很简单,new 了一个Button对象,让当前这个对象的内容添加Button的一个实例.

最简单的集合项

<ComboBox Height="23" SelectedIndex="0" HorizontalAlignment="Left" Margin="127,12,0,0" Name="comboBox1" VerticalAlignment="Top" Width="120">

            <ComboBoxItem>A</ComboBoxItem>

            <ComboBoxItem>B</ComboBoxItem>

</ComboBox>

这个xaml描述的是一个下拉框,其实如果对asp.net比较熟悉,这样的代码一看就明白了,xaml也就好学了.

既然讲到了xaml,布局等,给出一个下载地址,有一个简单的布局代码,给大家下载.

http://115.com/file/e7hbk0je

当然,你也可以写麻烦一点的布局.

比如

<ComboBoxItem>

                <Rectangle Fill="Red" Width="70" Height="20"></Rectangle>

 </ComboBoxItem>

也可以在集合项里面写一个Rectangle,或者别的控件.也可以这样插入一张给图片,反正你想怎么写就怎么写,xaml的解析能力很强大的.

<ComboBoxItem>

                <Rectangle Width="70" Height="20">

                    <Rectangle.Fill>

                        <ImageBrush ImageSource="E:\学习代码\WPF代码\Test2\Xaml1\超频美女.jpg"></ImageBrush>

                    </Rectangle.Fill>

                </Rectangle>

</ComboBoxItem>

既然讲了一个集合项讲了,这么多,还要一些别的集合项,大家自己动手吧…

Xaml语法,继续解析

1,类型转换器,什么事类型转换器呢

<Button Width="100" Height="100">

            <Button.Background>red</Button.Background>           

</Button> 先看看这段代码, <Button.Background>red</Button.Background>,为什么我直接写一个red,就可以解析出来对应的颜色,就是类型转换器的功劳..

var a = System.Windows.Media.ColorConverter.ConvertFromString("#FFCCCCCC");

 System.Windows.MessageBox.Show(a.ToString());

 var b = new System.Windows.Media.BrushConverter().ConvertFromString("Red");

 System.Windows.MessageBox.Show(b.ToString());

看这一段代码,这是wpf里面的类型转换器,可以把red转换成argb值.wpf的xaml也是通过转换器把值转换为颜色.

2,引用值和标记扩展.

先来看看引用值,怎么定义和引用..

在grid上面定义资源,

<Window.Resources>

        <SolidColorBrush x:Key="backgroundBrush">Yellow</SolidColorBrush>

        <SolidColorBrush x:Key="borderBrush">Red</SolidColorBrush>

</Window.Resources>

定义了两个简单的资源文件.在下面的代码中,将学习一下怎么引用这些定义的资源文件

<Button Background="{StaticResource backgroundBrush}" BorderBrush="{StaticResource borderBrush}" Width="100" Height="100"></Button>

先来分析一下这行代码, Background="{StaticResource backgroundBrush}" 使用了静态资源backgroundBrush

你可以写 Background=”{里面会提示使用,静态资源,绑定,动态资源等选项,我们选择使用静态资源,然后我们空格一下 写下你要使用的资源的key 就可以.}”

在这里,要说一下我们的强大的编辑器,visual studio,你可以使用文档大纲,从树形结构很容易的看出,你这个xaml的层次,以及每行xaml语法,所呈现的样式,这些功能很强大..

3, 事件和xaml代码隐藏,

Wpf和asp.net一样 ,都在直接在UI上面写代码,wpf的代码隐藏就是这样的,没上面变化..

<Button Width="100" Height="100" Click="button_Click" Content="Close"></Button>

        <x:Code>

            <![CDATA[

                void button_Click(object sender,RoutedEventArgs e)

                {

                this.Close();

            }

            ]]>           

        </x:Code>

Button下面写的就是隐藏代码.不支持调试,我用vs2010旗舰版 不支持提示,总体来说,wpf的代码隐藏功能做的很烂.

其实既然有了前台潜入代码,也就可以实现前台潜入代码调用后台代码,后台代码,调用前台潜入代码,很简单..

 

这一章,先写这么多了,快过年了,很多事,来总结一下这章,先是了解了xaml语法的构成,了解了集合项的绑定,以及复杂的呈现,然后是类型转换器,资源,和代码嵌入写法..

下一章会是关于布局的一些知识,以及资源样式. 

未完待续….

posted @ 2012-01-13 10:16 crud 阅读(282) 评论(0) 编辑

学了一段时间的WPF,虽然没有在项目中运用,就抽时间在博客里记录下来.写博客的目的是增加自己的理解,以前帮助刚学的朋友们,了解一下WPF.

WPF(Windows Presentation Foundation),先了解一下WPF的核心框架.

document service 提供了基于的打印和报表服务,通过这些组件实现自定义的打印和显示效果.

user interface service  controls(控件库)关于布局以及数据绑定

core Presentation  包含了2d图形,3d图形,文本,视频,音频,和显示效果,同时还包括了强大的动画效果.

base service 提供了xaml的支持,输入和事件的支持,属性系统等.

WPF核心体系结构和作用

Sharp(图形元素基类) Control(控件模板) Panel(布局基类)  继承自  frameworkElement(框架的属性集,事件集,以及方法集) 继承自 UIElement(数据模板的元素) 继承自 visual(生成可视化对象树) 继承自 DependencyObject(属性系统) 继承自 DispatcherObject(线程分配系统)

WPF中的基本对象 Application\Window\Navigation\Dispacher

Application 和winfrom中的对象类似

window 对象相当于Page对象

Navigation用于页面间的导航控制.

Dispacher对象提供管理线程工作项队列的服务.

关于Application和window对象的简单代码就不写了,今天就写两个小例子,一个关于导航和,一个关于线程的

Navigation是一个导航对象,也就是能像web页面那样支持导航,前进后退等功能,

新添加两个Page页,来演示一下导航的简单用法.

第一个页当导航页使用,第二个页面没什么大的用处,在第一个页的构造函数里面加上 this.KeepAlive = true;这行代码,意思是在导航历史中记录.

添加3个Button,我目前写代码,用到的几个导航的方式,

第一种导航的例子

Page2 page = new Page2();    //new 一个page2的对象 想的于winfrom的跳转页面.        

NavigationService ns = NavigationService.GetNavigationService(this);   //获得导航器NavigationService          

ns.Navigate(page); //异步导航到某个对象  也就是new 出来的对象page2

第二种导航的例子

NavigationService ns = NavigationService.GetNavigationService(this);            

ns.Source = new Uri("Page2.xaml", UriKind.Relative); //直接使用Uri地址导航,UriKind.Relative使用一个相对的Uri路径

第三种导航的例子

NavigationService ns = NavigationService.GetNavigationService(this);            

ns.Content = new Page2(); //直接使用导航对象的Content 直接指向page2页

返回的方法

if (this.NavigationService.CanGoBack)                

this.NavigationService.GoBack(); //如果有一个返回的条目,就返回

前进的方法

if (this.NavigationService.CanGoForward)                

this.NavigationService.GoForward(); //如果有下个条目,就导航

刷新也不一样了 this.NavigationService.Refresh(); 需要用NavigationService对象的Refresh方法来刷新.

下面讲一下Dispacher对象,后续会讲,xaml,资源以及样式,绑定,路由,等一些基础的东西,这些基础的内容会在一周内更新完成.

拖一个Label 一个 ProgressBar 一个 Button ,好了,这次就需要一个页面就搞定了,做什么 相信大家以及明白了.

然后 我们只需要在Button的Click事件里面把代码完成了,就行了.

定义一个委托 private delegate void RefUIL(string var);

在Button的Click事件里面加上这个些代码

for (int i = 0; i <= 100; i++)            

 {

       //WPF中的线程又被封装了  用 Dispatcher来管理,上面已经说了,              

    this.Dispatcher.BeginInvoke(new RefUIL(RefUI), DispatcherPriority.Normal, new string[] { i.ToString() });                                            System.Threading.Thread.Sleep(100);                

    this.DoEvents();   // 这是自己实现的一个扩展方法 代码下面会解释         

}    

 RefUI方法在这里

//相信这样的代码在winfrom里面写很多,就是跨线程赋值..

private void RefUI(string var)        

 {             this.label1.Content = var;             this.progressBar1.Value = int.Parse(var);         }

下面是一个扩展类 就是扩展window 这个对象

 public static class Ext    

{        

  //一个扩展方法 对Window对象进行扩展

  public static void DoEvents(this Window win)        

  {            

    //表示Dispatcher中的执行循环            

    DispatcherFrame frmae = new DispatcherFrame();            

     //当前的线程异步执行              并进行回调  如果没有回调 只能执行一次

    Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background, new DispatcherOperationCallback(Exit), frmae);            

    //进入执行循环            

    Dispatcher.PushFrame(frmae);        

   }   

   /// 让线程继续执行          

    public static object Exit(object obj)        

     {            

        ((DispatcherFrame)obj).Continue = false;         //一个比较有意思的值,     false为继续,true为停止

         return null;        

    }    

} //对于这段代码的理解就是,让DispatcherFrame 在Dispatcher执行循环,然后异步回调一个函数,并每次继续执行

WPF系列一,大概分为5篇博客,会把一些基础的东西讲完.然后在考虑将2D,3D,因为我学的时候主要应用是3D效果,到时候给大家推荐两个挺好的工具,后话(如果大家找不到免费版本,我也可以免费传给大家).

posted @ 2012-01-06 14:23 crud 阅读(481) 评论(2) 编辑

继上次发了一篇博客,ajax的应用以来,这是本菜鸟在博客园的第二篇文章.

由于第一篇博客,大家反映是会的没用,不会的嫌多.那么,这篇博客,不会又丑又长的.只是会简单介绍服务器推模型的好处,以及我自己使用中发现的问题..

我希望大家看了这篇博客,一定要看完,并不是写的多好,因为最后 我会给出web.config的配置节点代码,如果会自己配置的当我没说.

先啰嗦几句话. 在我不会推模型之前,我一直都是拉模型,也就是让js代码每隔一段时间向服务器索取数据,并刷新,当然,肯定是异步刷新..

今天看了看推模型,并写了简单的代码.不多说,如果会拉模型的,感觉感觉comet的妙处吧..

由于本次代码全是手写,不保证没错

 

<由于几个类都是实现接口,通过配置文件,实现htm页面访问,所以还是看完吧>

(创建一个项目,asp.net web项目.然后创建一个类,继承自IHttpHandler接口,)

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

 

namespace Comet

{

//继承并实现了 IHttpHandler   接口

  public class MyHandler : IHttpHandler   

    {        

//这个属性,和方法 都是实现 IHttpHandler 的

     public bool IsReusable   

        {           

      get { return true; }    

       }

         public void ProcessRequest(HttpContext context)      

     {       

//设置不让客服端缓存

        context.Response.Cache.SetCacheability(HttpCacheability.NoCache);      

 

         List<MyAsyncResult> userlist = MyAsyncHandler.Queue;

            string sessionId = context.Request.QueryString["sessionId"];     

          string message = context.Request.QueryString["message"];

            foreach(MyAsyncResult res in userlist)            

     {

//如果不是自己就推

                 if (res.SessionId != sessionId)        

          {               

      //激发callback,结束请求      

         res.Message = message;                    

                 res.SetCompleted(true);                  

       }

            }

         }

    }

(接着第二个类,实现IHttpAsyncHandler接口)

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

 

namespace Comet

{

  public class MyAsyncHandler : IHttpAsyncHandler

{

//这个集合 用于存放 所有请求的

  public static List<MyAsyncResult> Queue = new List<MyAsyncResult>();

  public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)

{

   context.Response.Cache.SetCacheability(HttpCacheability.NoCache);

 string sessionId = context.Request.QueryString["sessionId"];

//查找Queue这个集合  SessionId ==传过来的sessionId  !=null

 if (Queue.Find(q => q.SessionId == sessionId) != null) 

{

int index = Queue.IndexOf(Queue.Find(q => q.SessionId == sessionId));

//把HttpContext对象的实例等于当前请求的所有信息

 Queue[index].Context = context;

 Queue[index].CallBack = cb;

return Queue[index];

}

//MyAsyncResult 这个类是 回调的参数类(相当于 你定义一个事件 使用的泛型的   public event EventHandler<MyEvargs> Events;  MyEvargs这个类继承了EventArgs  同样的道理)

 MyAsyncResult asyncResult = new MyAsyncResult(context, cb, sessionId);

 Queue.Add(asyncResult);

return asyncResult;

}

这个方法是这个异步接口的另一个方法

  public void EndProcessRequest(IAsyncResult result)  

       {          

   MyAsyncResult rslt = (MyAsyncResult)result;      

//向别的客服端推送  某个 客服端发送的 信息 

      rslt.Context.Response.Write(rslt.Message);      

       rslt.Message = string.Empty;       

  }

//为什么不实现这个方法  (因为IhttpAsyncHandler接口继承了IHttpHandler这个接口,所以实现接口的时候,就实现了它,但是 我们不管它)

  #region IHttpHandler 成员 不实现

        public bool IsReusable      

   {          

   get { return true; }    

     }

        public void ProcessRequest(HttpContext context)      

   {

        }

        #endregion

}

}

下面是参数类,这个类 比较简单 但是 所有的数据 都是经过这些个参数的,回调 才是关键

using System;

using System.Collections.Generic;

 using System.Linq;

using System.Web;

 

namespace Comet

{

//就是继承了这个IAsyncResult接口,所以就可以是回调的参数类

     public class MyAsyncResult : IAsyncResult    

{       

//这个接口的实现

    public object AsyncState { get; private set; }

        public System.Threading.WaitHandle AsyncWaitHandle { get; private set; }

        public bool CompletedSynchronously { get { return false; }}

        public bool IsCompleted { get; private set; }       

//一些个参数

    public HttpContext Context { get; set; }    

       public AsyncCallback CallBack { get; set; }  

       public string SessionId { get; set; }      

     public string Message { get; set; }

//构造函数

        public MyAsyncResult(HttpContext context, AsyncCallback cb, string sessionId)    

     {            

    this.SessionId = sessionId;         

      this.Context = context;        

       this.CallBack = cb;       

  }

//这个方法对于的是MyHandler调用哪个方法,

//它的主要作用是,用某种浏览器检测工具,也就是能检测所有请求的工具,就能看出,它是结束当前的请求,在用js马上开始另一个请求,好处就是,感觉这个客服端是长连接的

        public void SetCompleted(bool iscompleted)   

      {      

         this.IsCompleted = iscompleted;     

          if (iscompleted && this.CallBack != null)       

          {

                CallBack(this);          

       }

        }

    }

}

//其实到现在 写的差不多了,我们已经实现了IHttpHandler IHttpAsyncHandler 这两个接口,并处理完了,最麻烦的回调,

剩下的就是,通过一个页面,来调用...  等下看配置文件..其实这个配置文件,已经可以实现了伪静态页面...

新建一个htm页面吧 什么名字无所谓了,代码直接 拿过去,配置文件 一定要配置哦,不然 上面的一切都是扯淡...呵呵

 

 

//这些代码

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

 <html xmlns="http://www.w3.org/1999/xhtml">

<head>   

  <title></title>

</head>

<body>   

  <input type="text" id="sessionId" /><input type="button" value="进入" onclick="comin()" /><br />    

 <input type="text" id="message" /><input type="button" value="发送" onclick="send()" />   

  <div id="messages"></div>    

<script type="text/javascript">

        function comin() {         

    var xmlHttp = ajaxFunction();      

       var url = "MyAsyncHandler.ashx?sessionId=" + document.getElementById("sessionId").value;       

      xmlHttp.onreadystatechange = function() {      

           if (xmlHttp.readyState == 4) {             

        if (xmlHttp.status == 200) {             

            document.getElementById("messages").innerHTML += xmlHttp.responseText + "<br>";        

                 //连接已经结束,马上开启另外一个连接     

//看看这句话 呵呵 感觉像无限的 递归

//服务器的一个推 结束,马上开始 继续 一个请求 等待    

                comin();        

             }          

       }        

     }        

     xmlHttp.open("get", url, true);   

          xmlHttp.send(null);    

     }

 

        function send() {          

   var xmlHttp = ajaxFunction();   

          var url = "MyHandler.ashx?sessionId=" + document.getElementById("sessionId").value + "&message=" + document.getElementById("message").value;       

 

      xmlHttp.onreadystatechange = function() {       

          if (xmlHttp.readyState == 4) {           

          if (xmlHttp.status == 200) {

                    }               

      else {                

         alert("服务器端错误");      

               }           

      }        

         else {        

             alert("服务器端错误");    

             }          

   }          

   xmlHttp.open("get", url, true);      

       xmlHttp.send(null);     

    }

 

        function $$(id) {             return typeof id == String ? document.getElementById(id) : id;         }

 

        function ajaxFunction() {       

      var xmlHttp;          

   try {           

      xmlHttp = new XMLHttpRequest();   

          }       

      catch (e) {      

           try {                

     xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");      

           }               

  catch (e) {       

              try {    

                     xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");   

                  }                

     catch (e) {               

          alert("您的浏览器不支持AJAX!");      

                   return false;           

          }             

    }          

   }        

     return xmlHttp;  

       }   

    </script>

</body>

</html>

放上配置文件的代码

<不要弄错了,,,找到httpHandlers节点,在里面, </httpHandlers>关闭节点的上面加上我给的代码,不然一切都是扯淡...>

(细讲一行)

<!-- add一个节点 verb="*" 这是一个通配符,相当于在 <authorization>节点配置 <allow users="*"/>它一样   -->

<!--path="MyHandler.ashx" 这个意思是 (上面的ajax  open的没有) 本来就是一个不存在的文件  通过配置文件 连接上的,伪静态页面 就是这样做的  -->

<!-- type="Comet.MyHandler"/ 它的意思是  path这个东西指向的类 -->

  <add verb="*" path="MyHandler.ashx" type="Comet.MyHandler"/>  

       <add verb="*" path="MyAsyncHandler.ashx" type="Comet.MyAsyncHandler"/>

啰嗦一句,伪静态页面的配置

<add verb="*" path="hello.htm,hello.html" type="指向实现了IHttpHandler的类"/> 

posted @ 2011-10-27 19:51 crud 阅读(2466) 评论(17) 编辑
摘要: 记得以前学的时候,网上的资料一大堆,就是没几个看的懂,都是理论,包括我目前看的mvc书都是一样,废话一堆,其实东西没那么难,让作者把某个技术吹上天了.下面是一些初学者,比较实用的代码,欢迎大虾指导....<ajax调用一般处理程序,并解析json数据><因为是测试代码,没有命名>创建一个静态页面default.html//下面是default.html的代码,直接考过去就可以了...<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3阅读全文
posted @ 2011-10-24 10:35 crud 阅读(909) 评论(1) 编辑