WPF-Web-Review

DotNew菜园的WPF入门教程系列回顾

Reference: http://www.cnblogs.com/chillsrc/p/4464023.html

CH01 Basic

小结:

都是基础中的基础,谈到WPF的开发,必须要学习MVVM,学习MVVM,就要首先了解MVC、MVP等概念。?

.net的本质没变,数据库的访问,文件的读写、日志处理、程序中异常的处理、报表、打印、性能的优化….

CH02 Application

WPF中常见的功能都封装在此类中,具体功能如下:

  • 跟踪应用程序的生存期并与之交互
  • 检索和处理命令行参数
  • 检测和响应未经处理的异常
  • 共享应用程序范围的属性和资源
  • 管理独立应用程序中的窗口
  • 跟踪和管理导航

主要讲代码Main方法启动WPF应用程序

自己新起一个App.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[STAThread]
public static void Main()
{
Application app = new Application();
app.StartupUri = new Uri("MainWindow.xaml", UriKind.Relative);
app.Run();
//or
MainWindow mainWindow = new MainWindow();
app.Run(mainWindow);
//or
//app.MainWindow = mainWindow;
//mainWindow.Show();
//app.Run();
}

CH03 Application_01

WPF Shutdown

ShutdownMode Properties:

OnLastWindowClosse OnMainWindowClose OnExplicitShutDown

Can modify it in App.xaml or in Background code

Application 对象的其他属性

Current Dispatcher MainWindow Properties ResourceAssembly Resources ShutdownMode StartupUri Windows

添加Application对象事件

Activated Deactivated DispatcherUnhandleException Exit FragmentNavigation LoadCompleted Navigated Navigating NavigationFailed NavigationProgress NavigationStopped SessionEnding Startup

CH04


Like Unity,从子线程中不能直接更新UI,Unity->用Loom可以办到,WPF采用Dispatcher.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private void ModifyUI()

{

Thread.Sleep(TimeSpan.FromSeconds(2));

this.Dispathcer.Invoke(DispatcherPriority.Normal,(ThreadStart)delegate()

{

label.Content = "Welcome";

});

}

另外一种方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
private void btnAppBeginInvoke_Click(object sender, RoutedEventArgs e)

{
new Thread(() =>

{

Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal,

new Action(() =>

{

Thread.Sleep(TimeSpan.FromSeconds(2));

this.lblHello.Content = "欢迎你光临WPF的世界,Dispatche 异步方法!!"+ DateTime.Now.ToString();

}));

}).Start();
}

CH05

第一次打开窗口时,只有在引发了Activated事件以后,才会引发Loaded和ContentRendered事件。

窗口的生命周期

1
2
3
4
5
6
7
8
9
10
11
12
public MainWindow()
{
this.Activated += WindowThd_Activated;
this.Closing += WindowThd_Closing;
this.ContentRendered += WindowThd_ContentRendered;
this.Deactivated += WindowThd_Deactivated;
this.Loaded += WindowThd_Loaded;
this.Closed += WindowThd_Closed;
this.Unloaded += WindowThd_Unloaded;
this.SourceInitialized += WindowThd_SourceInitialized;
InitializeComponent();
}

1–SourceInitialized 2–Activated 3–Loaded 4–ContentRendered 5–Deactivated

1–Closing 2–Deactivated 3–Closed 4–Unloaded

CH06

Canvas 实例

1
2
3
4
5
6
7
8
9
Ellipse el = new Ellipse();
el.Fill = new SolidColorBrush(Colors.Blue);
el.Stroke = new SolidColorBrush(Colors.Blue);
el.Width = 240;
el.Height = 80;
el.SetValue(Canvas.ZIndexProperty, 1);
el.SetValue(Canvas.LeftProperty, (double)100);
el.SetValue(Canvas.TopProperty, (double)80);
canv.Children.Add(el);

Ch07

WarpPanel 排列?

StackPanel 填充排列

CH08

Grid

To use it, first to Add RowDefinitions & ColumnDefinitions

Ch09

DockPanel

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<Window x:Class="WpfApp1.WindowDock"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WindowDock" Height="300" Width="400">
<Grid>
<DockPanel Width="Auto" Height="Auto">
<Button DockPanel.Dock="Left" Content="1" />
<Button DockPanel.Dock="Top" Content="2" />
<Button DockPanel.Dock="Right" Content="3" />
<Button DockPanel.Dock="Bottom" Content="4" />
<Button HorizontalAlignment="Left" Name="btnAddByCode" Height="22" Width="65" DockPanel.Dock=" Left " Click="btnAddByCode_Click" >后台代码添加</Button>
</DockPanel>
</Grid>
</Window>

Viewbox

StretchDirection

Stretch

None 内容保持原样
Fill 填充
Uniform 适合目标尺寸\
UniformToFill 裁剪
UpOnly ?
DownOnly
Both

Ch10

Border

只有一个子控件,如果要多个,就加个Panel

Attributes

  • Background
  • BorderBrush
  • BorderThickness
  • CornerRadius
  • Paddding

ScrollViwer

1
2
3
4
5
6
7
<Grid>
<StackPanel>
<ScrollViewer Name="scroll" Width="480" Height="350" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Visible" >
<TextBlock Name="txtShowArticle" Foreground="Gray" Margin="20,10" />
</ScrollViewer>
</StackPanel>
</Grid>

ch11

依赖属性基本介绍

Aim: To Solve Style ,Binding,Animation.

Attributes: The Binding Attributes is that it Can have no value And get value from Binding Data Source.

Usage:

  • Double Oriention Binding

  • Trigger

  • Append Attribute

  • Attribute Change Binding

Advantage

  • New function
  • Save Ram
  • Support Multiple Object

Then How to Use:

  • heir your class from DependencyObject

  • The Defination of Attribute must use public static of DependencyProperty and the value has the Property to append

    1
    public static readonly DependencyProperty NameProperty;
  • How to register

1
NameProperty = DependencyProperty.Register("Name",typeof(string),typeof(Student),new PropertyMatadata("名称",OnValueChanged));
  • Sealing

    1
    2
    3
    4
    5
    public string Name
    {
    get{return(string)GetValue(nameProperty);}
    set{SetValue(NameProperty,value);}
    }

Then We can Write:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class Student: DependencyObject
{
//got a static readonly DependencyProperty
public static readonly DependencyProperty NameProperty;
static Student()
{
//register our Arribute Name
NameProperty = DependencyProperty.Register("Name",typeof(string),
typeof(Student),new PropertyMetadata("名称",OnValueChanged));
}
private static void OnValueChanged(DependencyObject o,DependencyPropertyChangeEventArgs e)
{
//when value change
}
//sealing Attributes
public string Name
{
get{return (string)GetValue(NameProperty);}
set{SetValue(NameProperty,value);}
}
}

Conclusions

The Binding Attribute Calls the GetValue() SetValue() which is heired form the DependencyProperty,which is a IDictionary, Key is the HashCode and the Value is The Dependency Property we registered.

CH12

img

Ch13

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public MainWindow()
{
InitializeComponent();
DispatcherTimer timer = new DispatcherTimer(TimeSpan.FromSeconds(1),
DispatcherPriority.Normal,
(object sender, EventArgs e) =>
{
int newValue = Counter == int.MaxValue ? 0 : Counter + 1;
SetValue(counterKey, newValue);
}, Dispatcher
);
}

public int Counter
{
get { return (int)GetValue(counterKey.DependencyProperty); }
}
private static readonly DependencyPropertyKey counterKey =
DependencyProperty.RegisterReadOnly("Counter",
typeof(int), typeof(MainWindow), new PropertyMetadata(0));

Append Attributes

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class TurnoverManager : DependencyObject
{
//通过静态方法的形式暴露读的操作
public static double GetAngle(DependencyObject obj)
{
return (double)obj.GetValue(AngleProperty);
}
public static void SetAngle(DependencyObject obj,double value)
{
obj.SetValue(AngleProperty, value);
}
public static readonly DependencyProperty AngleProperty =
DependencyProperty.RegisterAttached("Angle", typeof(double), typeof(TurnoverManager), new PropertyMetadata(0.0, OnAngleChanged));
private static void OnAngleChanged(DependencyObject obj,DependencyPropertyChangedEventArgs e)
{
var element = obj as UIElement;
if (element!=null)
{
element.RenderTransformOrigin = new Point(0.5, 0.5);
element.RenderTransform = new RotateTransform((double)e.NewValue);
}
}

}

How to Use

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<Grid.RowDefinitions>
<RowDefinition Height="313*"/>
<RowDefinition Height="57*"/>
</Grid.RowDefinitions>
<Canvas Grid.Row="0">
<Ellipse Name="ellipseRed" Fill="Red" Width="100" Height="60" Canvas.Left="56"
Canvas.Top="98" local:TurnoverManager.Angle="{Binding ElementName=sliderAngle,Path=Value}"/>
<Rectangle Name="rectBlue" Fill="Blue" Width="100" Height="80" Canvas.Left="285"
Canvas.Top="171" local:TurnoverManager.Angle="45"/>
<Button Name="btnWelcome" Content="Welcome" Canvas.Left="265" Canvas.Top="48"
FontSize="20" local:TurnoverManager.Angle="60"/>
</Canvas>
<WrapPanel Grid.Row="1">
<Label Content="Angle rate"/>
<Slider x:Name="sliderAngle" Minimum="0" Maximum="240" Width="300" />
</WrapPanel>

这个貌似需要生成。

CH14

没看懂

三依赖属性控制Slider的最大最小值,有空再看一下

CH15

What is Data Binding?

The target U want to bind is any Attribute & Component that Inheir from DependencyProperty。

Attributes

Mode:

  • Default
  • OneTime
  • OneWay
  • OneWayToSource
  • TwoWay

UpdateSourceTrigger:

  • Default
  • Explicit
  • LostFocus
  • PropertyChanged

https://images0.cnblogs.com/blog2015/10343/201508/061715297524204.png

Easy Example

1
<TextBlock Width="248" Height="24" Text="{Binding ElementName=listStockName, Path=SelectedItem.Content}">

CH16

绑定模式如何应用呢?下面是个人的一点见解:

​ 1)当只想让用户看到数据,而不希望用户去修改数据时,可以采用 OneWay 模式,类似winform中的只读属性。

​ 2)当希望用户可以对控件中的数据进行修改,同时让用户修改的数据更新到数据源(DataSet、对象、XML 或其他绑定控件)中时,可以使用 TwoWay 绑定。

​ 3)如果想让用户修改数据源中的数据,而又不想使用TowWay模式,就可以使用 OneWayToSource 绑定。OneWayToSource模式允许通过在原来被看作是绑定源的对象中放置绑定表达式,从而翻转源和目标。

​ 4)当你的界面中的一系列只读控件均被绑定了数据,并且当用户刷新了数据源时,希望绑定控件中的值仍保持不变,可以使用 OneTime 绑定。此外,当源没有实现 INotifyPropertyChanged 时,OneTime 绑定模式也是一个不错的选择。

说明:绑定目标中的修改何时去修改数据源

​ 在上面的例子中,TextBox 使用了 TwoWay 绑定模式,所以当TextBox 失去焦点时WPF会使用TextBox中的值改变ListBox中的值。如果你不想在TextBox失去焦点时,就去修改ListBox中的值,可以为 UpdateSourceTrigger 指定值,它是用于定义何时更新源的绑定属性。可以为 UpdateSourceTrigger 设置三个值:Explicit、LostFocus 和 PropertyChanged。

​ 如果将 UpdateSourceTrigger 设置为 Explicit,则不会更新源,除非从代码中调用 BindingExpression.UpdateSource 方法。设置为LostFocus ,(TextBox 控件的默认值)指示数据源绑定的控件失去焦点时才会更新。PropertyChanged 值绑定控件的绑定属性每次发生更改时就去更新数据源中的值。

CH17

XML Data Binding

XmlDataProvider need a x:Key

1
2
3
4
5
6
7
8
9
10
11
12
13
<Grid>
<StackPanel>
<StackPanel.Resources>
<XmlDataProvider x:Key="MyColors" Source="Colors.xml" XPath="colors">
</XmlDataProvider>
</StackPanel.Resources>
<TextBlock Width="258" Height="24" Text="XML DataBind:" TextWrapping="Wrap"/>
<ListBox x:Name="listXmlColor" Width="248" Height="56" IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding Source={StaticResource MyColors},XPath=color/@name}"/>
<TextBlock Width="248" Height="24" Text="Choose:"/>
<TextBlock Width="248" Height="24" Text="{Binding ElementName=listXmlColor,Path=SelectedValue,Mode=OneWay}"/>
</StackPanel>
</Grid>

xml

1
2
3
4
5
6
7
8
9
<?xml version="1.0" encoding="utf-8" ?>
<colors >
<color name="Pink"/>
<color name="Red"/>
<color name="Purple"/>
<color name="Cyan"/>
<color name="Gray"/>
<color name="Turquoise"/>
</colors>

ObjectDataProvider

Attributes

  • ConstructionParameters
  • MethodParameters
  • ObjectInstance
  • IsAsynchronous

通用数据模板 DataTemplate

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<Grid>
<StackPanel>
<StackPanel.Resources>
<ObjectDataProvider x:Key="students" ObjectType="{x:Type local:StudentService}" MethodName="GetStudentList"/>
<DataTemplate x:Key="studentLayout" DataType="students">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Name}" FontWeight="Bold" Foreground="Blue"/>
<TextBlock Text=","/>
<TextBlock Text="{Binding Path=Age}"/>
<TextBlock Text=","/>
<TextBlock Text="{Binding Path=Birthday}"/>
<TextBlock Text=","/>
<TextBlock Text="{Binding Path=Country}"/>
</StackPanel>
</DataTemplate>
</StackPanel.Resources>
<TextBlock Width="248" Height="24" Text="Object Data Bind:" TextWrapping="Wrap"/>
<ListBox x:Name="listObjectBind" Width="450" Height="100" IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding Source={StaticResource students}}"
ItemTemplate="{DynamicResource studentLayout}"/>
</StackPanel>
</Grid>

Ch18

对数据排序

binding to CollectionViewSource

1
2
3
4
5
6
<CollectionViewSource x:Key="studentsView" Source="{Binding Source={StaticResource students}}">
<CollectionViewSource.SortDescriptions>
<scm:SortDescription PropertyName="Name" Direction="Ascending" />
<scm:SortDescription PropertyName="Age" Direction="Descending" />
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>

Ch19

后面就是实例了 没有贴代码