




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、 能夠使用WPF技術(shù)編寫圖形圖像程序 掌握三類(sn li)繪制圖形的方法 掌握畫筆、畫刷繪圖形工具 能夠進(jìn)行圖形變換 能夠如何處理圖像和剪貼板 了解WPF 3D圖形 學(xué)習(xí)(xux)目的第1頁(yè)/共153頁(yè)第一頁(yè),共154頁(yè)。主要(zhyo)內(nèi)容 5.1 WPF和GDI 5.2 常用的結(jié)構(gòu) 5.3 使用Shape派生類 5.4 使用Drawing派生類 5.5 使用Visual類派生類 5.6 Pen類和Brush類 5.7 圖形變換(binhun) 5.8 位圖效果 5.9 處理圖像 5.10 圖像剪貼板功能 5.11 3D圖形 5.12 DirectX 3D和XNA介紹 第2頁(yè)/共153頁(yè)第
2、二頁(yè),共154頁(yè)。5.1 WPF和GDI WPF和GDI的圖形圖像編程方法有很大不同。 GDI一般采用即時(shí)模式顯示圖形和圖像,當(dāng)窗口圖形和圖像被破壞后,程序員要自己在OnPaint事件處理函數(shù)中恢復(fù)被破壞的圖形和圖像。而WPF采用保留模式顯示圖像,一般由WPF系統(tǒng)自己恢復(fù)被破壞的圖形和圖像。 WPF控件外觀一般用矢量圖形實(shí)現(xiàn),控件能夠(nnggu)記錄生成控件矢量圖形的方法,當(dāng)外觀需要恢復(fù)時(shí)自動(dòng)調(diào)用這些方法重現(xiàn)自己外觀。這樣做的好處是圖形外觀和顯示器分辨率無(wú)關(guān),能夠(nnggu)自適應(yīng)不同分辨率顯示器。 第3頁(yè)/共153頁(yè)第三頁(yè),共154頁(yè)。 WPF提供了三類顯示圖形的方法,它們是: Syst
3、em.Windows.Shapes.Shape類派生類:這些類都是控件,設(shè)置必要的屬性,就可以繪制所需要的圖形。這類控件最容易使用,但是由于這些控件支持布局和數(shù)據(jù)綁定等功能,能夠響應(yīng)較多的事件,使用這些控件將會(huì)大大增加應(yīng)用程序的資源消耗,一般只用來(lái)在窗口顯示少量的圖形。 System.Windows.Media.Drawing類派生類:這些類都支持XAML,能夠?qū)崿F(xiàn)Shape類派生類相同的功能。這類控件只支持少量的事件及少量的功能,使用這類控件將能極大(j d)減少資源消耗,相對(duì)于Shape類派生類要寫較多的XAML標(biāo)記。 System.Windows.Media.Visual類派生類:這些類
4、對(duì)XAML支持有限,繪制圖形方法類似GDI+,一般要編寫大量的代碼,使用類的方法繪制圖形,其占用的資源最少 第4頁(yè)/共153頁(yè)第四頁(yè),共154頁(yè)。5.2 常用(chn yn)的結(jié)構(gòu) 5.2.1 Point和Size結(jié)構(gòu)點(diǎn)結(jié)構(gòu)System.Windows.Point定義點(diǎn)的位置,點(diǎn)結(jié)構(gòu)有兩個(gè)成員:X,Y,表示點(diǎn)的x軸和y軸的坐標(biāo)。其構(gòu)造函數(shù)如下:public Point(double x,double y)System.Windows.Size結(jié)構(gòu)用屬性Width和Height描述(mio sh)對(duì)象寬和高。其構(gòu)造函數(shù)如下:public Size(double width,double heig
5、ht) 第5頁(yè)/共153頁(yè)第五頁(yè),共154頁(yè)。5.2.2 Rect結(jié)構(gòu)(jigu) 矩形結(jié)構(gòu)System.Windows.Rect,用來(lái)描述一個(gè)矩形,其常用屬性和方法如下: 屬性X、Y:矩形結(jié)構(gòu)左上角的x、y坐標(biāo)。 只讀屬性Left、Top:矩形結(jié)構(gòu)左上角的x、y坐標(biāo)。 只讀屬性Right和Bottom:矩形結(jié)構(gòu)對(duì)象右下角的x坐標(biāo)和y坐標(biāo)。 屬性Width、Height和Size:矩形結(jié)構(gòu)對(duì)象的寬度(kund)和高度。 構(gòu)造函數(shù)Rect(Point location, Size size):參數(shù)1代表矩形結(jié)構(gòu)左上角點(diǎn)結(jié)構(gòu),參數(shù)2是表示代表矩形寬和高的Size結(jié)構(gòu)。第6頁(yè)/共153頁(yè)第六頁(yè),共1
6、54頁(yè)。 構(gòu)造函數(shù)Rect(Double x, Double y, Double width, Double height):參數(shù)依次為矩形左上角x坐標(biāo)、y坐標(biāo)、寬和高。還有其他三個(gè)構(gòu)造函數(shù),請(qǐng)參考幫助系統(tǒng)有關(guān)內(nèi)容。 靜態(tài)方法public static Rect Intersect(Rect rect1,Rect rect2):返回Rect結(jié)構(gòu),是兩個(gè)參數(shù)表示的矩形結(jié)構(gòu)的交集。如果(rgu)沒(méi)有交集,則返回空。交集概念見(jiàn)5.4.4節(jié)。 方法public void Intersect(Rect rect):得到調(diào)用該方法的矩形結(jié)構(gòu)對(duì)象和參數(shù)表示的矩形結(jié)構(gòu)的交集。 靜態(tài)方法public stati
7、c Rect Union(Rect rect1,Rect rect2):返回Rect結(jié)構(gòu),是兩個(gè)參數(shù)表示的矩形結(jié)構(gòu)的并集。并集概念見(jiàn)5.4.4節(jié)。參數(shù)2也可為Point。 方法public bool Contains(Point或Rect):判斷參數(shù)表示的點(diǎn)或矩形結(jié)構(gòu)是否在調(diào)用該方法的矩形結(jié)構(gòu)對(duì)象中。第7頁(yè)/共153頁(yè)第七頁(yè),共154頁(yè)。5.2.3 Color結(jié)構(gòu)(jigu) System.Windows.Media.Color結(jié)構(gòu)用來(lái)表示顏色。任何一種顏色可以用透明度(a),藍(lán)色(b),綠色(g),紅色(r)合成。Color結(jié)構(gòu)支持兩種色彩(sci)空間sRGB和scRGB。sRGB用無(wú)符號(hào)
8、32位數(shù)代表一種顏色,紅色、綠色、藍(lán)色以及透明度各占一個(gè)字節(jié),透明度等于0為完全透明,255為完全不透明,完全不透明紅色用16進(jìn)制數(shù)表示為:#ffff0000。scRGB代表的顏色中的紅色、綠色、藍(lán)色以及透明度分別用0-1之間的Single類型數(shù)表示,透明度等于0.0為完全透明,1.0為完全不透明,紅色、綠色、藍(lán)色全為0.0表示黑色,全為1.0表示白色,不透明紅色表示為:sc#1.0,1.0,0.0,0.0。第8頁(yè)/共153頁(yè)第八頁(yè),共154頁(yè)。 其常用屬性和方法如下: 屬性R、G、B和A:分別(fnbi)表示sRGB空間的紅色、綠色、藍(lán)色以及透明度。 屬性scR、scG、scB和scA:分別
9、(fnbi)表示scRGB空間的紅色、綠色、藍(lán)色以及透明度。 public static Color FromRgb(byte r,byte g,byte b):得到不透明sRGB顏色。 public static Color FromArgb(byte a,byte r,byte g,byte b):sRGB顏色。 public static Color FromScRgb(float a,float r,float g,float b):scRGB顏色。 public static bool AreClose(Color color1,Color color2):由于scRGB顏色可能無(wú)法
10、完全相等,用此函數(shù)比較兩個(gè)scRGB顏色是否近似相等。第9頁(yè)/共153頁(yè)第九頁(yè),共154頁(yè)。5.3 使用(shyng)Shape派生類 Shape派生類包括(boku)畫線段控件Line、畫矩形控件Rectangle、畫圓或橢圓控件Ellipse、畫多條線段控件Polyline、畫由多條線段組成的閉合圖形控件Polygon和畫任意曲線控件Path。 5.3.1 公用屬性 Fill:Brush類對(duì)象,指定封閉圖像的填充顏色。 Stroke: Brush類對(duì)象,指定線的顏色或封閉圖形外輪廓線的顏色。 StrokeThickness: 指定線的寬度或封閉圖形外輪廓線的寬度。 GeometryTran
11、sform:對(duì)圖形位置進(jìn)行變換。 第10頁(yè)/共153頁(yè)第十頁(yè),共154頁(yè)。5.3.2 畫線控件Line 控件Line用來(lái)畫線段,屬性X1和Y1為線段起點(diǎn),屬性X2和Y2為線段終點(diǎn)?!纠?.1】畫一條線段的XAML標(biāo)記如下,注意實(shí)際程序必須(bx)添加省略的標(biāo)記。 第11頁(yè)/共153頁(yè)第十一頁(yè),共154頁(yè)。5.3.3 畫矩形(jxng)控件Rectangle 控件Rectangle可用來(lái)畫各種矩形,屬性Width、Height、RadiusX和RadiusY分別(fnbi)是矩形的寬、高、圓角矩形的圓角x 軸半徑和y 軸半徑。x 軸半徑要小于等于Width二分之一,y 軸半徑要小于等于Heigh
12、t二分之一,當(dāng)二者都等于二分之一,則圖形變?yōu)閳A或橢圓。第12頁(yè)/共153頁(yè)第十二頁(yè),共154頁(yè)。【例5.2】畫矩形和圓角矩形的XAML標(biāo)記(bioj)如下,如果Width=Height,為正方形。 第13頁(yè)/共153頁(yè)第十三頁(yè),共154頁(yè)?!纠?.3】用代碼生成矩形(jxng),為Grid控件添加屬性Name=grid1,在窗體增加按鈕,其事件函數(shù)如下,單擊按鈕,則出現(xiàn)一個(gè)黑輪廓線,內(nèi)部填充天藍(lán)色的正方形。private void button1_Click(object sender, RoutedEventArgs e) Rectangle myRect = new Rectangle()
13、; myRect.Stroke = Brushes.Black; myRect.Fill = Brushes.SkyBlue; myRect.Height = 50; myRect.Width = 50; RotateTransform rotateTransform1 = new RotateTransform(-45); myRect.RenderTransform = rotateTransform1; grid1.Children.Add(myRect); 第14頁(yè)/共153頁(yè)第十四頁(yè),共154頁(yè)?!纠?.4】繪制3個(gè)重疊的矩形,演示透明效果(xiogu)。將如下標(biāo)記放到Grid標(biāo)記中
14、。請(qǐng)讀者仔細(xì)分析運(yùn)行后不同位置為什么會(huì)產(chǎn)生相應(yīng)顏色。 第15頁(yè)/共153頁(yè)第十五頁(yè),共154頁(yè)。5.3.4 畫圓或橢圓(tuyun)控件Ellipse 控件Ellipse畫橢圓時(shí)如果Width=Height,則為圓。 【例5.5】本例用鍵盤4個(gè)箭頭鍵推動(dòng)一個(gè)紅色圓,可以在窗體的4個(gè)方向上移動(dòng),當(dāng)圓到了窗體邊界,圓就不能繼續(xù)移動(dòng)了。 (1)創(chuàng)建WPF項(xiàng)目。放置Ellipse控件到Grid面板,拖動(dòng)Ellipse控件向左上方移動(dòng),一直(yzh)到只有左方和上方的兩根指示距離邊界的線(圖5.1),修改Ellipse控件的控制邊界顏色屬性Stroke=Red,控制填充顏色屬性Fill=Red。此時(shí)El
15、lipse控件XAML標(biāo)記如下: 第16頁(yè)/共153頁(yè)第十六頁(yè),共154頁(yè)。 (2)選中Window1窗體,為其增加KeyDown事件(shjin)函數(shù)如下: private void Window_KeyDown(object sender, KeyEventArgs e) double x1 = ellipse1.Margin.Left; double x2 = ellipse1.Margin.Top; switch (e.Key) case Key.Left: if (ellipse1.Margin.Left 0) x1 -= 1; break; case Key.Right: if (
16、ellipse1.Margin.Left+100) this.Width ) x1 += 1; break; 第17頁(yè)/共153頁(yè)第十七頁(yè),共154頁(yè)。 case Key.Down: if (ellipse1.Margin.Top+100 0) x2 -= 1; break; ellipse1.Margin = new Thickness(x1, x2, 0, 0); (3)運(yùn)行,可以(ky)用4個(gè)箭頭鍵移動(dòng)紅色圓。第18頁(yè)/共153頁(yè)第十八頁(yè),共154頁(yè)?!纠?.6】Windows畫圖程序用拖動(dòng)鼠標(biāo)方法畫橢圓或圓,實(shí)現(xiàn)的方法是以鼠標(biāo)左鍵單擊處作為矩形的一個(gè)頂點(diǎn),記為頂點(diǎn)1,該點(diǎn)坐標(biāo)不改變。拖
17、動(dòng)鼠標(biāo)移動(dòng)到另一位置,以此位置作為矩形另一頂點(diǎn),記為頂點(diǎn)2,頂點(diǎn)1和頂點(diǎn)2在矩形對(duì)角線的兩端。繪制由頂點(diǎn)1和頂點(diǎn)2定義(dngy)的矩形的內(nèi)切橢圓,以顯示要繪制橢圓的位置,這個(gè)橢圓的位置隨著鼠標(biāo)的移動(dòng)而改變。鼠標(biāo)抬起,以鼠標(biāo)抬起位置為頂點(diǎn)2,用指定的顏色繪制由頂點(diǎn)1和頂點(diǎn)2定義(dngy)的矩形的內(nèi)切橢圓,作為最終圖形。具體步驟如下。(1)創(chuàng)建WPF項(xiàng)目。放置Ellipse控件到面板中,拖動(dòng)Ellipse控件向左上方移動(dòng),一直到只有左方和上方的兩根指示距離邊界的線。此時(shí)Ellipse控件XAML標(biāo)記見(jiàn)例5.5。(2)為面板增加名字屬性:(3)為Window1類增加變量:double x, y;
18、 bool mark = false;第19頁(yè)/共153頁(yè)第十九頁(yè),共154頁(yè)。(4)在Window1類中增加MakeRectangle方法,參數(shù)(x1,y1)是鼠標(biāo)左鍵單擊處點(diǎn)的位置,作為矩形的一個(gè)(y )頂點(diǎn),(x2,y2)是拖動(dòng)鼠標(biāo)移動(dòng)到另一點(diǎn)的位置,返回一個(gè)(y )數(shù)組,4個(gè)元素按順序分別是定義所畫橢圓或圓矩形的左上角x、y座標(biāo),矩形寬和高。方法如下:private double MakeRectangle(double x1, double y1,double x2,double y2) double top, left, bottom, right; top = y1 = y2 ?
19、 y1 : y2; left = x1 y2 ? y1 : y2; right = x1 x2 ? x1 : x2; double xs = left, top, right-left , bottom-top ; return xs;第20頁(yè)/共153頁(yè)第二十頁(yè),共154頁(yè)。 (5)為Window1事件MouseDown、MouseUp、MouseMove增加(zngji)事件處理函數(shù)如下: private void Window_MouseDown(object sender, MouseButtonEventArgs e) if (e.LeftButton = MouseButtonSt
20、ate.Pressed) ellipse1.Visibility = Visibility.Visible; Point position = e.GetPosition(grid1); x = position.X; y = position.Y; ellipse1.Width = 1; ellipse1.Height = 1; ellipse1.Margin = new Thickness(x, y, 0, 0); mark = true; 第21頁(yè)/共153頁(yè)第二十一頁(yè),共154頁(yè)。private void Window_MouseMove(object sender, MouseEve
21、ntArgs e) if (mark ) Point position = e.GetPosition(grid1); double pX = position.X; double pY = position.Y; double xs = MakeRectangle(x, y, pX, pY); ellipse1.Width = xs2; ellipse1.Height = xs3; ellipse1.Margin = new Thickness(xs0, xs1, 0, 0); private void Window_MouseUp(object sender, MouseButtonEve
22、ntArgs e) mark = false; (6)編譯(biny)運(yùn)行,在Window1控件中拖動(dòng)鼠標(biāo)可以畫圓或橢圓。第22頁(yè)/共153頁(yè)第二十二頁(yè),共154頁(yè)。5.3.5 控件Polyline和Polygon Polyline類的屬性Ponints是點(diǎn)結(jié)構(gòu)數(shù)組,將數(shù)組元素Ponints0和Ponints1、Ponints1和Ponints2、等點(diǎn)連接為多條線段。Polygon和Polyline類功能類似,但將最后一點(diǎn)和開(kāi)始點(diǎn)連接為線段,由多條線段組成封閉圖形(txng)。實(shí)際上如設(shè)置類Polyline屬性IsClose=true,也能完成Polygon類相同功能。XAML標(biāo)記例子: 【例
23、5.7】在Windows畫圖程序中,可以拖動(dòng)鼠標(biāo)畫任意曲線。本例實(shí)現(xiàn)用拖動(dòng)鼠標(biāo)左鍵在主窗體中畫曲線。每條曲線都是由若干很短的線段組成。鼠標(biāo)左鍵在按下?tīng)顟B(tài),移動(dòng)鼠標(biāo),每次移動(dòng)很短距離,畫出這段線段,所有這些線段組合起來(lái),形成一條曲線。第23頁(yè)/共153頁(yè)第二十三頁(yè),共154頁(yè)。 (1)創(chuàng)建WPF項(xiàng)目。在面板中增加Polyling控件XAML標(biāo)記。 (2)為Window1類增加如下(rxi)變量: PointCollection myPoints=new PointCollection(); bool mark = false; (3)為Window1控件增加事件處理函數(shù): private voi
24、d Window_MouseDown(object sender, MouseButtonEventArgs e) myPoints.Clear(); Point p1 = e.GetPosition(grid1); myPoints.Add(p1); mark = true; 第24頁(yè)/共153頁(yè)第二十四頁(yè),共154頁(yè)。private void Window_MouseMove(object sender, MouseEventArgs e) if (mark) Point p1 = e.GetPosition(grid1); myPoints.Add(p1); polyline1.Poin
25、ts = myPoints; private void Window_MouseUp(object sender, MouseButtonEventArgs e) mark = false; (4)運(yùn)行(ynxng),在主窗體中拖動(dòng)鼠標(biāo)左鍵可以畫線。第25頁(yè)/共153頁(yè)第二十五頁(yè),共154頁(yè)。5.3.6 控件Path 使用Path控件可以畫任意曲線。 【例5.8】使用Path控件例子。在Grid標(biāo)記(bioj)中增加如下標(biāo)記(bioj): 第26頁(yè)/共153頁(yè)第二十六頁(yè),共154頁(yè)。 屬性Data也可采用路徑標(biāo)記語(yǔ)法賦值,上例中第二個(gè)Path控件采用路徑標(biāo)記語(yǔ)法生成貝塞爾曲線,依靠XMAL解析
26、器內(nèi)部類型(lixng)轉(zhuǎn)換器自動(dòng)將路徑標(biāo)記轉(zhuǎn)換為Geometry 對(duì)象。該標(biāo)記中,逗號(hào)前后的兩個(gè)數(shù)值表示一個(gè)點(diǎn),點(diǎn)與點(diǎn)之間用空格分開(kāi),字符M或m表示Path起點(diǎn),L或l表示線段終點(diǎn)(起點(diǎn)是當(dāng)前點(diǎn)),H或h后的一個(gè)數(shù)值(不是點(diǎn))表示x坐標(biāo)值,表示當(dāng)前點(diǎn)到這個(gè)x坐標(biāo)的水平線段,V或v后的一個(gè)數(shù)值表示y坐標(biāo)值,表示當(dāng)前點(diǎn)到這個(gè)y坐標(biāo)的垂直線段,C或c表示三次貝塞爾曲線控制點(diǎn),Q或q表示二次貝塞爾曲線控制點(diǎn),T或t表示平滑貝塞爾曲線控制點(diǎn),A或a表示橢圓弧指令,Z或z表示Path終點(diǎn)。第27頁(yè)/共153頁(yè)第二十七頁(yè),共154頁(yè)。5.4 使用(shyng)Drawing派生類 5.4.1 繪圖基本方法
27、GeometryDrawing類用來(lái)繪制各種形狀圖形,其屬性Geometry用來(lái)描述圖形的形狀,屬性Brush用來(lái)指定填充封閉圖形的刷子,屬性Pen指定繪制輪廓的筆。該類必須放在承載容器才能顯示所繪制的圖形,承載容器必須是FrameworkElement 類的派生類,例如窗口(chungku)或其它內(nèi)容控件,常用的用法是GeometryDrawing類對(duì)象放到DrawingImage控件中,作為Image控件的數(shù)據(jù)源。 第28頁(yè)/共153頁(yè)第二十八頁(yè),共154頁(yè)?!纠?.9】本例繪制橢圓,將如下標(biāo)記放到Grid標(biāo)記中。這是Drawing類繪圖基本(jbn)方法。 第29頁(yè)/共153頁(yè)第二十九頁(yè)
28、,共154頁(yè)?!纠?.10】可以使用XAML標(biāo)記或代碼(di m)繪制圖形。public Window1() InitializeComponent(); EllipseGeometry ellipse2 = new EllipseGeometry(); ellipse2.RadiusX = 45; ellipse2.RadiusY = 20; ellipse2.Center = new Point(50, 50); GeometryDrawing aDrawing = new GeometryDrawing(); aDrawing.Geometry = ellipse2; aDrawing.
29、Brush = Brushes.Orange; aDrawing.Pen = new Pen(Brushes.Black, 10.0); DrawingImage di = new DrawingImage(aDrawing); Grid grid = new Grid(); Image image = new Image(); grid.Children.Add(image); image.Source = di; this.Content = grid; 第30頁(yè)/共153頁(yè)第三十頁(yè),共154頁(yè)。5.4.2 Geometry類 【例5.11】本例繪制圓角矩形,將如下XAML標(biāo)記替換例5.9
30、相應(yīng)(xingyng)XAML標(biāo)記。 【例5.12】本例繪制一條線段,將如下XAML標(biāo)記替換例5.9相應(yīng)(xingyng)XAML標(biāo)記。 第31頁(yè)/共153頁(yè)第三十一頁(yè),共154頁(yè)。【例5.13】本例使用PathGeometry類繪制兩條線段,將如下XAML標(biāo)記(bioj)替換例5.9相應(yīng)XAML標(biāo)記(bioj)。 第32頁(yè)/共153頁(yè)第三十二頁(yè),共154頁(yè)?!纠?.14】本例使用多條首尾連接(linji)線段類PolyLineSegment屬性Points路徑標(biāo)記語(yǔ)法重做上例。用如下XAML標(biāo)記替換上例兩條線段的XAML標(biāo)記,顯示效果相同。 【例5.15】如果有兩組不連接(linji)或不是
31、首尾連接(linji)的圖形,可以放到兩個(gè)PathFigure標(biāo)記中。將如下XAML標(biāo)記替換例5.9相應(yīng)XAML標(biāo)記。 第33頁(yè)/共153頁(yè)第三十三頁(yè),共154頁(yè)。 第34頁(yè)/共153頁(yè)第三十四頁(yè),共154頁(yè)。5.4.3 GeometryGroup類 如同時(shí)繪制多個(gè)RectangleGeometry、EllipseGeometry、LineGeometry或PathGeometry圖形,就必須將它們放到標(biāo)記GeometryGroup中。在標(biāo)記中,每個(gè)圖形都可以使用屬性Transform分別實(shí)現(xiàn)(shxin)旋轉(zhuǎn)、縮放、扭曲和平移等變換。 【例5.16】用如下標(biāo)記替換例5.9相應(yīng)標(biāo)記。 第35頁(yè)
32、/共153頁(yè)第三十五頁(yè),共154頁(yè)。5.4.4 CombinedGeometry類 區(qū)域是封閉曲線所圍內(nèi)部平面部分。區(qū)域可以是簡(jiǎn)單(jindn)的(如單個(gè)矩形內(nèi)部)或復(fù)雜的(如多邊形或閉合曲線的組合)。圖5.6中的左邊第1圖顯示了兩個(gè)區(qū)域相交,一個(gè)矩形和一個(gè)用曲線畫出的封閉圖形??梢酝ㄟ^(guò)合并現(xiàn)有兩個(gè)區(qū)域來(lái)創(chuàng)建復(fù)雜區(qū)域。兩個(gè)區(qū)域的交集(Intersect)是同時(shí)屬于兩個(gè)區(qū)域的所有點(diǎn)的集合,并集(Union)是多個(gè)區(qū)域的所有點(diǎn)的集合,兩個(gè)區(qū)域并集減去這兩者的交集,即圖5.6中的左數(shù)第4圖顯示的黑色區(qū)域,稱作異或(Xor)??蓮木匦螀^(qū)域除去和另一個(gè)區(qū)域的交集,如圖5.6中右數(shù)第1圖區(qū)域,稱作Excl
33、ude。 第36頁(yè)/共153頁(yè)第三十六頁(yè),共154頁(yè)?!纠?.17】用如下XAML標(biāo)記(bioj)替換例5.9相應(yīng)XAML標(biāo)記(bioj),從Geometry1標(biāo)記(bioj)內(nèi)的橢圓除去和Geometry2標(biāo)記(bioj)內(nèi)的橢圓相交部分。 第37頁(yè)/共153頁(yè)第三十七頁(yè),共154頁(yè)。5.5 使用(shyng)Visual類派生類 Visual類是一個(gè)抽象類,其派生類DrawingVisual 是一個(gè)輕量(qn lin)繪圖類,用于呈現(xiàn)形狀、圖像或文本,它不提供布局、輸入、焦點(diǎn)或事件處理功能,從而能夠改善其性能。必須將DrawingVisual 對(duì)象放到一個(gè)派生自 FrameworkElem
34、ent 類的宿主容器,例如窗體、Image類對(duì)象、Panel類對(duì)象等。類DrawingVisual對(duì)XAML支持很少,大部分圖形要用代碼實(shí)現(xiàn)。 第38頁(yè)/共153頁(yè)第三十八頁(yè),共154頁(yè)。5.5.1 繪圖(hu t)基本方法 【例5.18】使用DrawingVisual繪制一個(gè)(y )橢圓和矩形。其代碼如下:public partial class Window1 : Window private VisualCollection _children; DrawingVisual dv = new DrawingVisual(); public Window1() _children = ne
35、w VisualCollection(this); InitializeComponent(); _children.Add(dv); using (DrawingContext dc = dv.RenderOpen() Rect rect = new Rect(new Point(100, 100), new Size(100, 50); 第39頁(yè)/共153頁(yè)第三十九頁(yè),共154頁(yè)。 dc.DrawRectangle(Brushes.Blue, (Pen)null, rect); dc.DrawEllipse(Brushes.Red, (Pen)null, new Point(100, 50
36、), 100, 50); protected override int VisualChildrenCount get return _children.Count; protected override Visual GetVisualChild(int index) if (index _children.Count) throw new ArgumentOutOfRangeException(); return _childrenindex; 第40頁(yè)/共153頁(yè)第四十頁(yè),共154頁(yè)。5.5.2 DrawingContext類方法(fngf) 【例5.19】本例用DrawDrawing方
37、法繪制使用GeometryDrawing方法生成的圖形(txng)。用如下語(yǔ)句替換例5.18的Using語(yǔ)句中代碼。EllipseGeometry ellipse2 = new EllipseGeometry();ellipse2.RadiusX = 45;ellipse2.RadiusY = 20;ellipse2.Center = new Point(50, 50);GeometryDrawing aDrawing = new GeometryDrawing();aDrawing.Geometry = ellipse2;aDrawing.Brush = Brushes.Orange;dc.
38、DrawDrawing(aDrawing); 第41頁(yè)/共153頁(yè)第四十一頁(yè),共154頁(yè)?!纠?.20】本例介紹DrawGeometry方法用法。用如下語(yǔ)句(yj)替換例5.18的Using語(yǔ)句(yj)中代碼。dc.DrawGeometry(Brushes.Red, (Pen)null, Geometry.Parse(M 0,0 0,100 100,100 Z); 第42頁(yè)/共153頁(yè)第四十二頁(yè),共154頁(yè)。5.6 Pen類和Brush類 5.6.1 Pen類Pen類包括如下屬性(shxng):Thickness和 Brush:筆的粗細(xì)和筆使用的刷子。DashStyle:默認(rèn)值為實(shí)線,也可為虛
39、線或點(diǎn)劃線,其子屬性(shxng)Dashes是一個(gè)數(shù)組,表示虛線或點(diǎn)劃線樣式,例如Dashes=a,b中的a和b是數(shù)字,a表示是一個(gè)寬為Thickness (筆的粗細(xì)),長(zhǎng)為(a+1)*Thickness 的線,其后為空格,按照此規(guī)律重復(fù),重復(fù)周期長(zhǎng)度為(a+b)* Thickness。因此Dashes=0,1表示實(shí)線。如果Dashes=a1,b1,a2,b2,則(a1,b1)和(a2,b2)意義同前,重復(fù)周期長(zhǎng)度為(a1+b1+a2+b2)*Thickness。數(shù)組可以有多項(xiàng),但必須為偶數(shù)項(xiàng)。 第43頁(yè)/共153頁(yè)第四十三頁(yè),共154頁(yè)?!纠?.21】為字符增加虛下劃線的XAML標(biāo)記如下,
40、注意(zh y)省略了一些標(biāo)記。帶下劃線字符 第44頁(yè)/共153頁(yè)第四十四頁(yè),共154頁(yè)。 DashCap、EndLineCap和StartLineCap:前兩個(gè)屬性是曲線末端的形狀,第3個(gè)屬性是曲線開(kāi)始的形狀,可以是枚舉類型PenLineCap的值:Flat(一個(gè)未超出直線上最后(zuhu)一點(diǎn)的線帽,等同于無(wú)線帽)、Square(一個(gè)高度等于直線粗細(xì)、長(zhǎng)度等于直線粗細(xì)一半的矩形)、Round 一個(gè)直徑等于直線粗細(xì)的半圓形)、Triangle(一個(gè)底邊長(zhǎng)度等于直線粗細(xì)的等腰直角三角形)。 LineJoin:兩條線段連接處的形狀??梢允敲杜e類型PenLineJoin的值:Miter(常規(guī)角頂點(diǎn)
41、)、Bevel(斜角頂點(diǎn))、Round(圓角頂點(diǎn))。第45頁(yè)/共153頁(yè)第四十五頁(yè),共154頁(yè)?!纠?.22】本例顯示(xinsh)Pen類屬性LineJoin、EndLineCap和StartLineCap的具體形狀。將如下XAML標(biāo)記增加到Grid記中,運(yùn)行效果見(jiàn)圖 。第46頁(yè)/共153頁(yè)第四十六頁(yè),共154頁(yè)。5.6.2 SolidColorBrush畫刷 又稱作單色畫刷,使用單一顏色填充封閉區(qū)域。一般控件屬性Background,Shape類屬性Fill,GeometryDrawing類屬性Brush是一個(gè)畫刷,如果令其為單一顏色值,實(shí)際上設(shè)置該屬性為SolidColorBrush單色
42、畫刷類對(duì)象,例如:。單色畫刷類SolidColorBrush最常用的屬性Color,表示畫刷的顏色。 【例5.23】使用SolidColorBrush單色畫刷例子。將XAML標(biāo)記(bioj)放到Grid標(biāo)記(bioj)中。 第47頁(yè)/共153頁(yè)第四十七頁(yè),共154頁(yè)。 又稱作顏色線形漸變畫刷。其常用屬性如下: StartPoint和EndPoint:Point結(jié)構(gòu)對(duì)象(duxing),顏色將沿著兩點(diǎn)連線漸變。 GradientStops:GradientStop 類對(duì)象(duxing)的集合。GradientStop 類表示漸變的位置和顏色。位置是StartPoint和EndPoint兩點(diǎn)連線
43、用分?jǐn)?shù)表示的相對(duì)值,例如,0.5表示連線中間位置。例如下例中,從連線開(kāi)始(0.0)到四分之一處(0.25),從黃色漸變到紅色,從四分之一處到連線終點(diǎn),從紅色漸變到藍(lán)色。 5.6.3 LinearGradientBrush畫刷 第48頁(yè)/共153頁(yè)第四十八頁(yè),共154頁(yè)。【例5.24】本例繪制(huzh)用顏色線形漸變畫刷填充的矩形。將以下標(biāo)記放到Grid標(biāo)記中。 第49頁(yè)/共153頁(yè)第四十九頁(yè),共154頁(yè)?!纠?.25】本例用代碼(di m)實(shí)現(xiàn)上例相同功能。Rectangle diagonalFillRectangle = new Rectangle();diagonalFillRectan
44、gle.Width = 200;diagonalFillRectangle.Height = 100; LinearGradientBrush myLinearGradientBrush = new LinearGradientBrush();myLinearGradientBrush.StartPoint = new Point(0, 0);myLinearGradientBrush.EndPoint = new Point(1, 1);myLinearGradientBrush.GradientStops.Add(new GradientStop(Colors.Yellow, 0.0);m
45、yLinearGradientBrush.GradientStops.Add(new GradientStop(Colors.Red, 0.25); myLinearGradientBrush.GradientStops.Add(new GradientStop(Colors.Blue, 1.0);diagonalFillRectangle.Fill = myLinearGradientBrush;Content = diagonalFillRectangle; 第50頁(yè)/共153頁(yè)第五十頁(yè),共154頁(yè)。5.6.4 RadialGradientBrush畫刷 又稱作顏色徑向漸變畫刷。其常用屬性
46、如下: Center、RadiusX和RadiusY:定義一個(gè)(y )矩形,顏色沿該矩形的內(nèi)切橢圓或圓徑向漸變。三個(gè)屬性意義分別是內(nèi)切橢圓或圓的圓心、水平半徑和垂直半徑。 GradientOrigin:顏色漸變開(kāi)始的點(diǎn)。 GradientStops:意義和LinearGradientBrush同名屬性類似。 第51頁(yè)/共153頁(yè)第五十一頁(yè),共154頁(yè)?!纠?.26】本例繪制用顏色徑向漸變(jinbin)畫刷填充的矩形。將以下標(biāo)記放到Grid標(biāo)記中。 第52頁(yè)/共153頁(yè)第五十二頁(yè),共154頁(yè)。5.6.5 ImageBrush畫刷 【例5.27】本例在窗體中顯示一幅(y f)圖像。Stretch
47、屬性參見(jiàn)5.6.6節(jié)。 第53頁(yè)/共153頁(yè)第五十三頁(yè),共154頁(yè)?!纠?.28】本例用代碼在矩形中顯示一幅圖像(t xin)。在構(gòu)造函數(shù)中增加如下語(yǔ)句。Rectangle exampleRectangle = new Rectangle();exampleRectangle.Width = 75;exampleRectangle.Height = 75;ImageBrush myBrush = new ImageBrush(); myBrush.ImageSource=new BitmapImage(new Uri(.p.bmp, UriKind.Relative);exampleRecta
48、ngle.Fill = myBrush;Content = exampleRectangle; 第54頁(yè)/共153頁(yè)第五十四頁(yè),共154頁(yè)。5.6.6 TileBrush類 TileBrush類是ImageBrush、DrawingBrush和VisualBrush基類,其常用屬性如下: Stretch:該屬性是Stretch枚舉類型,可以取值為:None、Fill、Uniform、UniformToFill。 Viewport 和 ViewportUnits:默認(rèn)情況下TileBrush畫刷完全填充被填充對(duì)象(duxing),也可僅填充一部分。Viewport決定填充大小和位置,Viewpo
49、rtUnits決定了Viewport是使用絕對(duì)坐標(biāo)還是相對(duì)坐標(biāo)指定的。 TileMode:設(shè)置該屬性可使畫刷以基本圖塊為基礎(chǔ),形成多個(gè)基本圖塊,按照一定規(guī)律排列。該屬性為TileMode枚舉類型值,可取值為:None、Tile、FlipX、FlipY、FlipXY。 第55頁(yè)/共153頁(yè)第五十五頁(yè),共154頁(yè)?!纠?.29】本例將在矩形中顯示(xinsh)4個(gè)基本圖塊。 第56頁(yè)/共153頁(yè)第五十六頁(yè),共154頁(yè)。5.6.7 DrawingBrush畫刷 【例5.30】本例在窗體中顯示一幅圖像(t xin)。注意基本塊為被填充矩形左上角第一行的一黑、一白,第二行的一白、一灰4個(gè)小矩形,在X和Y
50、方向各重復(fù)4次。 第57頁(yè)/共153頁(yè)第五十七頁(yè),共154頁(yè)。 第58頁(yè)/共153頁(yè)第五十八頁(yè),共154頁(yè)。5.6.8 VisualBrush畫刷 【例5.31】本例在窗體中顯示4個(gè)按鈕。屬性TileMode、Viewport參見(jiàn)5.6.6節(jié)。 OK 第59頁(yè)/共153頁(yè)第五十九頁(yè),共154頁(yè)。5.7 圖形(txng)變換 5.7.1 Transform 派生類Transform類是實(shí)現(xiàn)二維變換功能的一些(yxi)類的基類,其派生類包括RotateTransform(旋轉(zhuǎn))、ScaleTransform (縮放)、SkewTransform (扭曲) 和TranslateTransform (
51、平移)。RotateTransform類:其常用屬性包括Angle 、CenterX 和 CenterY , 該類使圖形圍繞點(diǎn)(CenterX,CenterY)旋轉(zhuǎn)指定的Angle角度。參見(jiàn)例5.2。ScaleTransform類:其屬性CenterX、CenterY指定縮放操作的中心點(diǎn),屬性ScaleX 和 ScaleY 指定圖形放大倍數(shù)。 第60頁(yè)/共153頁(yè)第六十頁(yè),共154頁(yè)?!纠?.32】本例定義了兩個(gè)矩形,然后(rnhu)寬和高分別放大2倍,但屬性CenterX、CenterY不同,注意兩者的不同,圖5.14中小矩形為初始位置,具體XAML標(biāo)記如下: 第61頁(yè)/共153頁(yè)第六十一頁(yè)
52、,共154頁(yè)。 第62頁(yè)/共153頁(yè)第六十二頁(yè),共154頁(yè)。 SkewTransform類:該類可用于對(duì)圖像進(jìn)行扭曲,其屬性CenterX和CenterY指定扭曲的中心點(diǎn),屬性AngleX和AngleY指定沿x軸和y軸的扭曲角度。 【例5.33】本例將矩形沿X軸扭曲45度,XAML標(biāo)記如下: TranslateTransform類:該類平移(pn y)圖像,屬性X和Y是沿X軸和Y軸方向距離。 第63頁(yè)/共153頁(yè)第六十三頁(yè),共154頁(yè)。5.7.2 TransformGroup類 如果要對(duì)一個(gè)(y )圖形完成多個(gè)變換,要將多個(gè)變換放到TransformGroup標(biāo)記中。 【例5.34】本例將一個(gè)
53、(y )按鈕沿Y軸方向放大3倍后,旋轉(zhuǎn)45度,XAML標(biāo)記如下:Click 第64頁(yè)/共153頁(yè)第六十四頁(yè),共154頁(yè)。5.7.3 Matrix結(jié)構(gòu)(jigu) 可以使用矩陣記錄所使用的變換。mn矩陣是以m行和n列排列的一組數(shù)字,例如一個(gè)33矩陣記如圖5.15。兩個(gè)行、列相同的矩陣可以相加,例如:a33+b33=c33,矩陣相加運(yùn)算的規(guī)則是:ci j=ai j+bi j,i和j為常量,即相對(duì)應(yīng)位置的項(xiàng)相加。如果有矩陣am n和bn k,am n矩陣的列數(shù)等于bn k矩陣的行數(shù),兩個(gè)矩陣可以相乘,記為:am n*bn k=cm k,矩陣相乘的運(yùn)算的規(guī)則是:ci j=(ai t*bt j),其中,
54、i和j為常量,t為變量,初始值為1,最大值為n。如果將平面中的點(diǎn)視為12矩陣,則可通過(guò)將該點(diǎn)乘以22變換矩陣來(lái)變形該點(diǎn)。圖5.16圖是點(diǎn)(2,1)在X軸按比例3放大(fngd),Y軸不變,變換結(jié)果如圖5.17。圖5.18表示點(diǎn)(2,1)旋轉(zhuǎn)了90度。圖5.19表示點(diǎn)(2,1)以x軸為對(duì)稱軸的新點(diǎn)。假定要從點(diǎn)(2,1)開(kāi)始,將其旋轉(zhuǎn)90度,在x方向?qū)⑵淦揭?個(gè)單位,在y方向?qū)⑵淦揭?個(gè)單位??赏ㄟ^(guò)先使用矩陣乘法再使用矩陣加法來(lái)完成此操作 第65頁(yè)/共153頁(yè)第六十五頁(yè),共154頁(yè)。 圖5.15 矩陣(j zhn) 圖5.16 矩陣(j zhn)相乘圖5.17 比例放大 圖5.18 點(diǎn)的旋轉(zhuǎn)(xu
55、nzhun) 圖5.19 點(diǎn)的對(duì)稱(duchn)變換 第66頁(yè)/共153頁(yè)第六十六頁(yè),共154頁(yè)。圖5.20 點(diǎn)的復(fù)合(fh)變換 圖5.21用仿射矩陣(j zhn)表示的復(fù)合變換 圖5.22 仿射矩陣(j zhn) 第67頁(yè)/共153頁(yè)第六十七頁(yè),共154頁(yè)。 如果用矩陣2 1 1代表點(diǎn)(2,1),用33變換矩陣記錄兩個(gè)變換,可用一個(gè)矩陣乘法代替以上的兩個(gè)矩陣運(yùn)算,見(jiàn)圖5.21。注意運(yùn)算結(jié)果(ji gu)的矩陣2 6 1代表點(diǎn)(2,6),即點(diǎn)(2,1)映射到了點(diǎn)(2,6)。這個(gè)33矩陣叫作仿射矩陣,它和前邊的兩個(gè)22矩陣的關(guān)系如圖5.22,其中第三列固定為0、0、1。WPF使用System.
56、Windows.Media.Matrix結(jié)構(gòu)封裝表示3行3列仿射矩陣,用來(lái)記錄圖形的復(fù)雜變換。Matrix結(jié)構(gòu)用屬性M11、M12、M21、M22、OffsetX和OffsetY表示33變換矩陣的各個(gè)項(xiàng),其結(jié)構(gòu)構(gòu)造函數(shù)如下: public Matrix(double m11,double m12,double m21,double m22,double offsetX,double offsetY) 第68頁(yè)/共153頁(yè)第六十八頁(yè),共154頁(yè)。 Matrix常用方法和屬性如下(rxi): 靜態(tài)屬性public static Matrix Identity get; :得到單位矩陣。 方法Rot
57、ate(double angle):使矩陣增加相對(duì)于原點(diǎn)順時(shí)針旋轉(zhuǎn)angle角度變換。 方法RotateAt(double angle,double centerX,double centerY):使矩陣增加相對(duì)于點(diǎn)(centerX,centerY)順時(shí)針旋轉(zhuǎn)angle角度變換。 方法Scale(double scaleX,double scaleY):使矩陣增加在X軸和Y軸方向?qū)D形放大或縮小的變換。參數(shù)1指定在X軸方向縮放的值,參數(shù)2指定在Y軸方向縮放的值。 方法Translate(double offsetX,double offsetY):使矩陣增加在(在)X軸和Y軸方向移動(dòng)的變換。參
58、數(shù)1指定在X軸方向移動(dòng)的值,參數(shù)2指定在Y軸方向移動(dòng)的值。 方法Point Transform(Point point):對(duì)point點(diǎn)進(jìn)行變換,參數(shù)也可為點(diǎn)數(shù)組 第69頁(yè)/共153頁(yè)第六十九頁(yè),共154頁(yè)。5.7.4 MatrixTransform 類 【例5.35】本例說(shuō)明MatrixTransform.類使用方法,如下(rxi)XAML標(biāo)記。Click 第70頁(yè)/共153頁(yè)第七十頁(yè),共154頁(yè)。然后在構(gòu)造函數(shù)最后增加如下(rxi)語(yǔ)句:Matrix m = myMatrixTransform.Matrix; m.Translate(-100, -100); myMatrixTransfo
59、rm.Matrix = m;第71頁(yè)/共153頁(yè)第七十一頁(yè),共154頁(yè)。5.7.5 控件的變換(binhun) 所有控件都可以使用Transform 派生類完成變換,例5.36是對(duì)控件Button進(jìn)行變換。所有控件都有屬性LayoutTransform和RenderTransform,前者是在布局之前對(duì)控件進(jìn)行變換,而后者則是在布局之后(zhhu)對(duì)控件進(jìn)行變換在窗體顯示。 【例5.36】本例使用LayoutTransform將Button2旋轉(zhuǎn)30度,運(yùn)行效果見(jiàn)圖5.25。如果修改Button.LayoutTransform為Button.RenderTransform,運(yùn)行效果如圖5.26
60、。 第72頁(yè)/共153頁(yè)第七十二頁(yè),共154頁(yè)。 Button1 Button2 Button3 第73頁(yè)/共153頁(yè)第七十三頁(yè),共154頁(yè)。5.7.6 Drawing類圖形(txng)變換 Geometry派生類RectangleGeometry、EllipseGeometry、LineGeometry、PathGeometry、GeometryGroup和CombinedGeometry都有屬性Transform,可令其等于RotateTransform(旋轉(zhuǎn)(xunzhun)、ScaleTransform (縮放)、SkewTransform (扭曲) 和TranslateTransfo
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 數(shù)學(xué) 2024-2025學(xué)年人教版七年級(jí)數(shù)學(xué)下冊(cè)期末綜合練習(xí)卷
- 2025年期貨從業(yè)資格之期貨基礎(chǔ)知識(shí)綜合練習(xí)試卷B卷附答案
- 壓縮天然氣在施工現(xiàn)場(chǎng)的應(yīng)用
- 和合谷快餐的節(jié)假日推廣與促銷活動(dòng)
- 房地產(chǎn)項(xiàng)目資源配置的優(yōu)化策略
- 冬妝 冬季肌膚保養(yǎng)與妝容技巧迎接冬日的溫暖
- 必勝客炸雞的特色菜品
- 保險(xiǎn)公司小年活動(dòng)策劃方案
- 保險(xiǎn)公司爆點(diǎn)活動(dòng)方案
- 保險(xiǎn)公司運(yùn)營(yíng)活動(dòng)方案
- 廣東中山市2023-2024學(xué)年三年級(jí)數(shù)學(xué)第二學(xué)期期末學(xué)業(yè)水平測(cè)試試題含解析
- 四川省涼山彝族自治州 2023-2024學(xué)年八年級(jí)下學(xué)期7月期末道德與法治試題
- 2024年安徽省高考生物試卷(真題+答案)
- 《學(xué)前兒童健康教育》6-2學(xué)前兒童安全教育的目標(biāo)和內(nèi)容課件
- 近五年廣東中考英語(yǔ)真題及答案
- 創(chuàng)業(yè)基礎(chǔ)智慧樹(shù)知到期末考試答案章節(jié)答案2024年山東大學(xué)
- 動(dòng)火作業(yè)安全管理協(xié)議書
- 《建筑施工塔式起重機(jī)安裝、使用、拆卸安全技術(shù)規(guī)程》(JGJ196-2010)
- 電費(fèi)代繳授權(quán)委托書模板
- 六年級(jí)下冊(cè)英語(yǔ)教案- Module 6 Unit 1 It was Damings birthday yesterday ∣外研版(三起)
- 舊樓外墻保溫合同
評(píng)論
0/150
提交評(píng)論