WCF学不会

c#笔记:Program.cs:源文件。
WPF视频笔记: .xaml(界面布局),.xaml.cs(窗体代码)
MainWindow类是构造器,调用IntializeComponent()方法。
App.xaml(显示xaml的描述,StartupUri属性,引用了.xaml)
MessageBox.Show();(消息框)
要在文本框中显示一个项目,必须设置文本框的Text属性(Text属性提供的数据必须是字符串)。
c#支持取模操作(%),c和c++不能对double和float类型的值使用取模操作符。
在c#中,一个整数除以一个整数,结果也是一个整数。
int.Parse()将字符串转化为整数,将文本框输入的内容转化为整数;
ToString方法,将一个对象转换为相应的字符串形式。outcome.ToString();
count++是返回递增发生前的count值,++count是返回递增发生后的count值。
var my=99;
var myboy=“hello”;//编译器根据初始化变量的表达式来推断变量的类型。必须是表达式。
int leftHandSide = System.Int32.Parse(lhsOperand.Text);//用户在lhsOperand文本框中输入的任何内容全部转化为int值。
int rightHandSide = System.Int32.Parse(rhsOperand.Text);
Console.write()和Console.writeline()方法类似,区别在于前者不会在消息之后输出一个换行符。
Console.WriteLine(“The consultant’s fee is:{0}”,p1.1);//{0}是一个占位符,会在运行时被替换成字符串后的表达式(P1.1)的值。

Lesson 02
wpf中xmal的标签是申明一个对象的
在XAML中为对象属性赋值
1。Attribute=value形式(大部分是通过字符串进行赋值)(详见HappyWPF项目)
2。属性标签形式(详情见WPF3项目)
3。 使用标签扩展的形式


导入程序集和引用其中的命名空间(详见BIAOQIANKUOZHANGWPF和ControlLibrary)
项目下面reference添加引用ControlLibrary

Windows x:对x名称空间的使用
xmlns:x 对x名称空间的申明

x名称空间详解:
x:null


Data Binding:

Binding基础:

6.3.1把控件作为Binding源与Binding的标记扩展

Bing构造器本身可以接受Path作为参数 6.3.2控制Binding的方向和数据更新 Binding数据流向的属性是Mode,它的类型是BindingMode枚举可取值OneWay,TwoWay,OnTime,OneWayToSource和Default,Default的值是指Binding的模式会根据实际情况来确定,若是可编辑的像TextBox.Text属性,Default就是双向的

6.3.6没有source的Binding–使用DataContext作为Binding的源
当UI上的多个控件都使用Binding关注同一个对象时,可以用DataContext

6.3.7使用集合对象作为列表控件的ItemsSource
InitializeComponent();
List stuList = new List()
{
new Student(){Id=0,Name=“Tim”,Age=29},
new Student(){Id=1,Name=“Tom”,Age=28},
new Student(){Id=2,Name=“Kyle”,Age=27},
new Student(){Id=3,Name=“Tony”,Age=26},
new Student(){Id=4,Name=“Vina”,Age=25},
new Student(){Id=5,Name=“Mike”,Age=24}
};
//为ListBox设置Binding
this.listBoxStudents.ItemsSource = stuList;
this.listBoxStudents.DisplayMemberPath = “Name”;
//为TextBox设置Bindig
this.textBoxId.SetBinding(TextBox.TextProperty, new Binding(“SelectedItem.Age”) { Source=this.listBoxStudents});

6.3.8使用ADO.NET对象作为Binding源


6.3.9使用xml数据作为Binding的源













private void Button_Click_1(object sender, RoutedEventArgs e)
{
XmlDocument doc = new XmlDocument();
doc.Load(@“D:\RawData.xml”);//文件地址
XmlDataProvider xdp = new XmlDataProvider();
xdp.Document = doc;
//使用Xpath选择需要暴露的数据
//现在是需要暴露一组Student
xdp.XPath = @"/StudentList/Student";
this.listViewStudents.DataContext = xdp;
this.listViewStudents.SetBinding(ListView.ItemsSourceProperty,new Binding());

或者: XmlDataProvider xdp = new XmlDataProvider();
xdp.Source = new Uri(@“D:\RawData.xml”);//指定XML文档所在的位置,调用xml文件的内容
xdp.XPath = @"/StudentList/Student";
this.listViewStudents.DataContext = xdp;
this.listViewStudents.SetBinding(ListView.ItemsSourceProperty,new Binding());
}

6.3.10使用LINQ检索结果作为Binding的源
使用LINQ,我们可以方便地操作集合对象,DataTable对象和XML而不必动辄就把好几层Foreach循环嵌套在一起
XAML:













C#:
using System.Xml.Linq;
private void Button_Click_1(object sender, RoutedEventArgs e)
{
//List stuList = new List()
//{
// new Student(){Id=0,Name=“Tim”,Age=29},
// new Student(){Id=1,Name=“Tom”,Age=28},
// new Student(){Id=2,Name=“Kyle”,Age=27},
// new Student(){Id=3,Name=“Tony”,Age=26},
// new Student(){Id=4,Name=“Vina”,Age=25},
// new Student(){Id=5,Name=“Mike”,Age=24},
//};
//this.listViewStudents.ItemsSource = from stu in stuList where stu.Name.StartsWith(“T”) select stu;//要从一个已经填充好的List对象中检索出所有名字为T开头的学生
XDocument xdoc = XDocument.Load(@“D:\RawData.xml”);//使用System.Xml.Linq命名空间才能使用这个方法//当数据存储在XML文件里
this.listViewStudents.ItemsSource = from element in xdoc.Descendants(“Student”)
where element.Attribute(“Name”).Value.StartsWith(“T”)
select new Student()
{
Id = int.Parse(element.Attribute(“Id”).Value),
Name = element.Attribute(“Name”).Value,
Age = int.Parse(element.Attribute(“Age”).Value)
};
}
}
}

6.3.11 使用ObjectDataProvider对象作为Binding的Source

很难保证一个类的所有数据都通过属性暴露出来,比如我们所需要的数据是方法的返回值,这时候就需要使用ObjectDataBinding作为Binding源的数据对象。ObjectDataBinding类的作用是用来包装以方法暴露数据的对象。
xaml:





c#:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        this.SetBinding();
    }

    private void SetBinding()
    {
        ObjectDataProvider odp = new ObjectDataProvider();//创建一个ObjectDataProvider
        odp.ObjectInstance = new Calculator();//然后用一个Calculator对象为ObjectInstance属性复制
        odp.MethodName = "Add";//指定要调用calculator方法中名为Add的方法
        odp.MethodParameters.Add("0");
        odp.MethodParameters.Add("0");

        //以ObjectDataProvider对象为Source创建Binding
        Binding bindingToArg1 = new Binding("MethodParameter[0]")
        {
            Source = odp,
            BindsDirectlyToSource=true,//告诉Binding对象只负责把UI元素手机的数据直接写入其Source
            UpdateSourceTrigger=UpdateSourceTrigger.PropertyChanged//有更新立刻传回Source

        };
        Binding bindingToArg2 = new Binding("MethodParameter[1]")
        {
            Source = odp,
            BindsDirectlyToSource = true,
            UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged

        };
        Binding bindingToResult = new Binding(".") { Source = odp };//当数据源本身就代表数据的时候就是要"."作Path

        //将Binding关联到UI元素上
        this.textBoxArg1.SetBinding(TextBox.TextProperty,bindingToArg1);
        this.textBoxArg2.SetBinding(TextBox.TextProperty, bindingToArg2);
        this.textBoxArg3.SetBinding(TextBox.TextProperty, bindingToResult);
    }
}

6.3.12 使用Binding的RelativeSource
XAML:










C#:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();

        RelativeSource rs = new RelativeSource(RelativeSourceMode.FindAncestor);
        rs.AncestorLevel = 2;//以Binding目标控件为起点的层级偏移量
        rs.AncestorType = typeof(DockPanel);//告诉Binding寻找哪个类型的对象作为自己的源,不是这个类型的对象会被跳过
        Binding binding = new Binding("Name") { RelativeSource = rs };
        this.textBox1.SetBinding(TextBox.TextProperty, binding);

      // RelativeSource rs = new RelativeSource();//TextBox关联自身的Name属性
       //  rs.Mode = RelativeSourceMode.Self;
       // Binding binding = new Binding("Name") { RelativeSource = rs };
       // this.textBox1.SetBinding(TextBox.TextProperty, binding);
    }
}

6.4.1 Binding的数据检验
类:重写 Validate方法
public class RangeValidationRule:ValidationRule
{
public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
{
double d = 0;
if (double.TryParse(value.ToString(), out d))
{
if (d >= 0 && d <= 100)
{
return new ValidationResult(true, null);

            }
        }
        return new ValidationResult(false, "Validation Failed");
    }
}

xaml:






c#:
public MainWindow()
{
InitializeComponent();
Binding binding = new Binding(“Value”) { Source = this.slider1 };
binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
RangeValidationRule rvr = new RangeValidationRule();//数据检验
rvr.ValidatesOnTargetUpdated = true;//检验Slider(Source)是否超出范围
binding.ValidationRules.Add(rvr);
this.textBox1.SetBinding(TextBox.TextProperty, binding);
}

c#:
public MainWindow()
{
InitializeComponent();
Binding binding = new Binding(“Value”) { Source = this.slider1 };
binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
RangeValidationRule rvr = new RangeValidationRule();//数据检验
rvr.ValidatesOnTargetUpdated = true;//检验Slider(Source)是否超出范围
binding.ValidationRules.Add(rvr);
binding.NotifyOnValidationError = true;//检验失败会发出警告
this.textBox1.SetBinding(TextBox.TextProperty, binding);

        this.textBox1.AddHandler(Validation.ErrorEvent, new RoutedEventHandler(this.ValidationError));
    }

    void ValidationError(object sender, RoutedEventArgs e)
    {
        if (Validation.GetErrors(this.textBox1).Count > 0)
        {
            this.textBox1.ToolTip = Validation.GetErrors(this.textBox1)[0].ErrorContent.ToString();//程序运行如果检验失败,TextBox的ToolTip就会提醒用户
        }
    }
}

6.4.2 Binding的数据转换
xaml:





















c#:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
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 Binding的数据转换
{
///
/// MainWindow.xaml 的交互逻辑
///
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}

    private void buttonLoad_Click(object sender, RoutedEventArgs e)
    {
        List planeList = new List()
        {
           new Plane(){Category=Category.Bomber,Name="B-1",State=State.Unknown},
           new Plane(){Category=Category.Bomber,Name="B-2",State=State.Unknown},
           new Plane(){Category=Category.Fighter,Name="F-22",State=State.Unknown},
           new Plane(){Category=Category.Fighter,Name="Su-47",State=State.Unknown},
           new Plane(){Category=Category.Bomber,Name="B-52",State=State.Unknown},
           new Plane(){Category=Category.Fighter,Name="J-10",State=State.Unknown}
        };
        this.listBoxPlane.ItemsSource = planeList;
    }

//保存到D盘
private void buttonSave_Click(object sender, RoutedEventArgs e)
{
StringBuilder sb = new StringBuilder();
foreach (Plane p in listBoxPlane.Items)
{
sb.AppendLine(string.Format(“Category={0},Name={1},State={2}”, p.Category, p.Name, p.State));
}
File.WriteAllText(@“D:\PlaneList.txt”,sb.ToString());
}
}
}

CategoryToSourceConverter:调用接口
public class CategoryToSourceConverter : IValueConverter
{ //
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
Category c = (Category)value;
switch ©
{
case Category.Bomber:
return @"\Icons\a.png";
case Category.Fighter:
return @"\Icons\b.png";
default:
return null;

        }

    }
   

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {

        throw new NotImplementedException();

    }
}

StateToNullableBoolConverter :
public class StateToNullableBoolConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
State s = (State)value;
switch (s)
{
case State.Locked:
return false;
case State.Available:
return true;
case State.Unknown:
default:
return null;

        }

    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        bool? nb = (bool?)value;
        switch (nb)
        {
            case true:
                return State.Available;
            case false:
                return State.Locked;
            case null:
            default:
                return State.Unknown;

        }


    }

6.5 MultiBinding(多路Binding)
xaml:








LogonMultiBindingConverter:
public class LogonMultiBindingConverter:IMultiValueConverter
{ //判断输入内容是否一致
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (!values.Cast().Any(text => string.IsNullOrEmpty(text))
&& values[0].ToString() == values[1].ToString()
&& values[2].ToString() == values[3].ToString())
{
return true;
}
return false;

    }
  

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

MainWindows:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.setMultiBinding();
}

    private void setMultiBinding()
    {   //准备好基础的Binding
        Binding b1 = new Binding("Text") { Source = this.textBox1 };
        Binding b2 = new Binding("Text") { Source = this.textBox2 };
        Binding b3 = new Binding("Text") { Source = this.textBox3 };
        Binding b4 = new Binding("Text") { Source = this.textBox4 };
        //准备MultiBinding
        MultiBinding mb = new MultiBinding() { Mode = BindingMode.OneWay };
        mb.Bindings.Add(b1);
        mb.Bindings.Add(b2);
        mb.Bindings.Add(b3);
        mb.Bindings.Add(b4);
        mb.Converter = new LogonMultiBindingConverter();
        this.button1.SetBinding(Button.IsEnabledProperty,mb);//
    }
}

第七章:
7.2 依赖属性:
一、CLR属性
CLR(Common Language Running)属性,本质是将一个类中的字段进行封装,以达到控制字段获取以及赋值的目的。
如下的Student类,作为一个学生,年龄显然不能为负数如果想要对age这一字段进行限制,我们可以采用CLR属性进行如下改写,
public class Student
{
public int id;
public string name;
public int age;
}
public class Student
{
public int ID { get; set; }
public string Name { get; set; }
private int age;
public int Age
{
get { return age; }
set
{
if (value > 0)
{
age = value;
}
}
}
}
采用CLR属性,可以很方便的控制某一字段的读和写,其本质其实就是类方法,类似于C++中封装的控制类对象成员获取和设置的方法。值得注意的是,WPF的Binding中Path的必须是CLR属性。

二、依赖属性(Dependency Property)
依赖属性的含义是自己没有值,能通过Binding从数据源获得值(依赖在别人身上)的属性,用于依赖属性的对象被称为依赖对象。

2.1 依赖属性减少了内存的开销。
在传统的.Net开发中,每一个类对象一旦被创建,它的所有字段也就被分配了存储空间,以TextBox为例,其包含了138个字段,一旦一个TextBox被创建,其138个字段也就被分配了内存空间,而我们常用的字段也就Text一个,这就造成了内存空间的浪费。依赖属性的出现,就是为了解决这一问题。WPF允许对象在创建时,不包含各个字段所占用的空间,而在使用这个字段时通过其他对象的数据或者实时分配空间,这种对象就是依赖对象,而它这种实时获取数据能力就是依靠依赖属性来实现。
WPF中支持依赖对象的类,需要继承自DependevcyObject,依赖属性的类需要继承自DependevcyProperty。DependevcyObject具有GetValue和SetValue两个方法,其都是以DependevcyProperty对象为参数,用于读取和存储依赖属性对象的值:

public class Student:DependencyObject
{

public object GetValue(DependencyProperty dp)
    {
        ...
    }

    public object SetValue(DependencyProperty dp,object value)
    {
        ...
    }

}

DependevcyObject是WPF中很底层的一个基类,所有的UI控件都是依赖对象。

2.2 依赖属性的使用
下面我们自已定义一个支持创建依赖对象的类Student,并设置其依赖属性:

public class Student:DependencyObject
{

    public static readonly DependencyProperty NameProperty =
        DependencyProperty.Register("Name", typeof(string), typeof(Student));

}

从上面的类中我们应该注意到:
1、该类必须继承自DependencyObject。
2、NameProperty是依赖属性,Name是用于包装NameProperty这个依赖属性的包装器,依赖属性的命名规范是“包装器+Property”。
3、依赖属性前必须由 public static readonly DependencyProperty修饰,其生成时并非由New,而是用DependencyProperty.Register
4、DependencyProperty.Register的三个参数以此是用来存储依赖属性值的CLR属性、该CLR属性的类型、该DependencyObject对象的类型。
其实从上面的定义我们也可以看出,其实依赖属性的本质就是一个全局的静态的DependencyProperty对象,当我们在开发WPF程序时,系统会准备一个全局的Dictionnary存储了由和“Name”和“Student”类经过某算法生成的唯一键和DependencyProperty的对象组成键值对。而在DependencyObject基类中保存了一个可变的Dictionnary,保存所有和该DependencyObject相关依赖属性的键值以及该属性值,每个DependencyObject对象都有这样一个容器。当使用SetValue对依赖属性进行赋值时,需要先从自带的容器中找到该依赖属性键值,然后 对对应的属性值进行赋值,如果没有就增加一个键值对。当使用GetValue进行依赖属性值的获取时,DependencyObject对象会在其 Dictionnary中进行查找,找到该依赖属性的键值后,返回对应的值,若没找到,返回DependencyProperty对应的默认值(该值在DependencyProperty存储)。
另外,至此对于WPF的Bingding也应该具有了一个更深的认识,其需要绑定Target属性就是依赖属性,而这也是依赖属性最主要的使用方面。
对应的XMAL代码:







对应的按钮事件处理函数:

private void button1_Click(object sender, RoutedEventArgs e)
{
Student stu = new Student();
stu.SetValue(Student.NameProperty, textBox1.Text);
textBox2.Text=stu.GetValue(Student.NameProperty) as string;
}

程序实现的效果就是在第一个编辑框输入某一个值时,会在第一个编辑框显示该值,而后台实现时先给Student对象的依赖属性NameProperty赋值,然后再读取。

而在通常情况下,我们在使用依赖属性时,都需要用CLR属性将其进行包装,这也是目前所有UI控件对依赖属性的处理方式:

public class Student:DependencyObject
{
public static readonly DependencyProperty NameProperty =
DependencyProperty.Register(“Name”, typeof(string), typeof(Student));

    public string Name
    {
        get { return (string)GetValue(NameProperty); }
        set { SetValue(NameProperty, value); }
    }

}

而按钮的点击事件就可改成:

private void button1_Click(object sender, RoutedEventArgs e)
{
Student stu = new Student();
stu.Name = textBox1.Text;
textBox2.Text = stu.Name;
}

这样我们就可以利用Student的CLR属性进行数据的绑定,作为Binding的path和目标,且虽然Student没有继承INotifyPropertyChanged接口,在CLR属性的值发生变化时,与之绑定的对象仍然可以得到通知,依赖属性默认带有这样的功能。

可以自己没有值,通过使用Binding在数据源身上获取值的属性。

Student.cs

using System.Windows;

namespace _7._2._2声明和使用依赖属性
{
public class Student:DependencyObject
{
public static readonly DependencyProperty NameProperty =
DependencyProperty.Register(“Name”, typeof(string), typeof(Student));
}
}

MainWindows:
using System.Windows.Shapes;

namespace _7._2._2声明和使用依赖属性
{
///
/// MainWindow.xaml 的交互逻辑
///
public partial class MainWindow : Window
{
Student stu;
public MainWindow()
{
InitializeComponent();
stu = new Student();
Binding binding = new Binding(“Text”) { Source = textBox1 };
BindingOperations.SetBinding(stu,Student.NameProperty,binding);
}

    private void Button_Click(object sender, RoutedEventArgs e)
    {
      
        stu.SetValue(Student.NameProperty, this.textBox1.Text);
        textBox2.Text = (string)stu.GetValue(Student.NameProperty);
        //MessageBox.Show(stu.GetValue(Student.NameProperty).ToString());
    }
}

}

7.3 附加属性
附加属性:一个属性本来不属于某个对象,但由于某种需求而被后来附加上。也就是把对象放入一个特定环境后才具有的属性(表现出来就是被环境赋予的属性)就称为附加属性。

8.3深入浅出路由事件

8.3.2自定义路由事件
创建自定义路由事件大体分为三个步骤:
(1)声明并注册路由事件

(2)为路由事件添加CLR事件包装

(3)创建可以激发路由事件的方法

附加事件:

9.1命令系统的基本元素与关系
9.1.1 命令系统的基本元素

ResourceDictionary:
https://www.cnblogs.com/theroad/p/6178795.html

Mvvm框架:https://www.cnblogs.com/fly-bird/

进程线程:
当今计算机操作系统中最普遍使用的一类操作系统:分时操作系统(采用时间片轮转的方式同时为多个进程服务,进一步加强CPU的使用率)分为协作式和抢占式

虚拟内存:

进程调度:

进程上下文切换:

一个应用程序对应一个进程,操作系统为该进程指定虚拟内存,映射实际的物理内存,从而做到进程隔离。

.NET引入应用程序域,并将它设置在进程和线程之间,显然,每一个进程会包括至少一个应用程序域。.NET允许我们在一个进程中创建一个新的应用程序域来加载程序集。程序集无论是.dll还是.exe,都是一个Windows可以理解的PE文件。如果项目有多个第三方dll,那么应用程序域就变得十分有用

一个进程可以有至少一个前台线程和任意个后台线程,前台线程使得整个进程得以继续下去。一个进程的所有前台线程都结束了,进程也就结束了。当该进程得所有前台线程终止时,CLR将强制终止该进程得所有后台线程,这将导致finally可能没来得及执行,进而导致一些垃圾回收的问题。

虚拟内存:是计算机系统内存管理的一种技术,它使得应用程序认为它拥有连续的可用空间(一个连续完整的地址空间),而实际上,它通常对应多个物理内存碎片,还有部分暂时存储在磁盘上,在需要时进行数据交换。

虚拟内存是按需分配,如果需要更多则会在其他可用内存中进行分配。此时,程序占据的内存(物理上)就不是连续的了。不过,虚拟内存进行映射后,程序会认为自己占据的内存是连续的。

进程隔离:是为保护操作系统中进程互不干扰而设计的技术。进程得隔离实现使用了虚拟内存,进程A的虚拟地址和进程B的虚拟地址不同,这样就防止进程A将数据信息写入进程B。

你可能感兴趣的:(WCF学不会)