日本國土百萬年的惡夢 每日數百噸的福島輻射污染水

文:宋瑞文(媽媽監督核電廠聯盟特約撰述)

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※教你寫出一流的銷售文案?

印度環境部長:解決首都空污時間 會比北京短

摘錄自2019年11月23日中央通訊社印度報導

印度環境、森林與氣候變遷部部長賈瓦德卡爾昨天(22日)在印度國會下院答詢時聲稱,空污需要大規模運動來解決,「北京花了15年的時間,我們將花費更少時間(解決空污問題)」。

印度包含新德里在內國家首都區每年冬天因農民焚燒農田殘梗、車輛排放、建築工地揚塵、6000家餐廳用炭火燒烤雞肉、窮人焚燒垃圾取暖等諸多因素,陷入嚴重空氣污染,但印度政府一直無法拿出有效解決對策。空污在今年11月更有惡化趨勢,引發民眾不滿。

賈瓦德卡爾指出,政府已針對城市制定監測空氣污染計畫,目前在全印度355個城市監測空污。此外,政府正每天展開工作以消除空污威脅,包括2018年啟用東、西部外環高速公路,且已把碳排放降低了22%;在第6期汽車廢氣排放標準(BS VI)明年4月實施後,汽車廢氣排放量將可減少80%。

他還把空污問題與氣候變遷聯繫起來,並說印度的總發電量在2030年之前,將有40%是來自可再生能源;而且印度的綠地覆蓋率不斷增加,使印度成為可達到綠地覆蓋率標準的少數國家之一,更五度在國家首都區種植更多樹木,以替代因興建地鐵而砍伐掉的樹木。

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※台北網頁設計公司全省服務真心推薦

※想知道最厲害的網頁設計公司"嚨底家"!

新北清潔公司,居家、辦公、裝潢細清專業服務

馬來西亞最後一頭蘇門答臘犀牛病逝 全球剩80頭

摘錄自2019年11月24日中央通訊社馬來西亞報導

馬來西亞最後一隻蘇門答臘犀牛,25歲的母犀牛伊曼自2014年被捕獲後,一直在野生動物保護區接受妥善照顧,牠今天(24日)因癌病逝於婆羅洲(Borneo)沙巴(Sabah)。沙巴野生動物部門(Sabah Wildlife Department)主任奧古斯丁(Augustine Tuuga)說:「伊曼的死亡比預期要快,但我們知道,牠已經開始承受極大痛苦。」

蘇門答臘犀牛是體型最小的犀牛,曾廣布亞洲各地,野生蘇門答臘犀牛如今已近乎絕種,據保育人士估計,目前全球僅剩約30至80頭,大多棲息在蘇門答臘和印尼所管轄的婆羅洲地區。馬來西亞2015年宣布野生蘇門答臘犀牛絕種,最後一頭公蘇門答臘犀牛今年5月離世。

保育團體國際犀牛基金會(International Rhino Foundation)說,棲地減少和盜獵導致蘇門答臘犀牛生存於孤立區域,代表牠們繁衍困難,數十年內可能就會滅絕。

自2011年以來,馬來西亞不斷嘗試以體外受精方式,繁殖人工飼養的蘇門答臘犀牛,但迄今尚未成功。

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

南投搬家費用,距離,噸數怎麼算?達人教你簡易估價知識!

※教你寫出一流的銷售文案?

韓國入冬後空氣污染物八成來自中國

摘錄自2019年11月21日大紀元報導

韓、日、中三國對大氣污染物流動的共同研究顯示,韓國境內有高達三成的細懸浮污染物(PM2.5)來自中國,入冬後這個數字更飆高至八成。

據韓聯社報導,韓國環境部下屬國立環境科學院20日發布報告概要指,韓日主要城市由國內因素導致污染的比例分別為51%和55%,而中國是91%。

從國外成因來看,韓國的空氣污染物中,來自中日兩國的各占32%和2%,其餘來自朝鮮、蒙古、東南亞等地區。從韓日兩國流入中國的空氣污染物比重分別僅占2%和1%,從韓中兩國流入日本的比重分別為8%和25%。

然而,如果將時間範圍限定在12月至3月,中國的空氣污染物對韓國的影響更為嚴重。據韓國國立環境科學院的調查,今年1月11日至15日韓國空氣污染物中只有18%至31%來自國內因素,其餘69%至82%來自國外,其中中國占絕大多數。

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※Google地圖已可更新顯示潭子電動車充電站設置地點!!

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※別再煩惱如何寫文案,掌握八大原則!

違法噴灑遭禁殺蟲劑 孟山都將付3億罰款

摘錄自2019年11月22日中央通訊社美國報導

美國農業生技巨擘孟山都(Monsanto)今天(22日)同意認罪,承認在夏威夷毛伊島(Maui)的設施對研究作物違法噴灑遭禁的劇毒殺蟲劑,將支付1000萬美元(約新台幣3億532萬元)罰款。

法新社報導,孟山都在提交給檀香山聯邦地區法院的法庭文件中承認,2014年在農場谷(Valley Farm)對玉米種子等作物噴灑Penncap-M殺蟲劑,即使已知環境保護署於2013年禁用這款化學物。

審理此案的加州中區聯邦檢察官韓納(Nick Hanna)說:「此案的違法行徑對環境、周圍社區和孟山都工人構成威脅。」他說:「聯邦法律與相關規範規定,使用管制和危險化學物的每個人,都有責任確保產品是經過安全儲存、運送與使用。」

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

南投搬家前需注意的眉眉角角,別等搬了再說!

新北清潔公司,居家、辦公、裝潢細清專業服務

新宿市民測定所 發表嬰幼兒奶粉輻射檢查報告

文:宋瑞文(媽媽監督核電廠聯盟特約撰述)

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※想知道最厲害的網頁設計公司"嚨底家"!

※幫你省時又省力,新北清潔一流服務好口碑

※別再煩惱如何寫文案,掌握八大原則!

一口氣投80億人民幣 比亞迪建長沙、青島兩個新能源車生產基地

比亞迪汽車於5月18日與湖南省長沙市雨花區經開區簽署合作備忘錄,比亞迪將投資50億元人民幣(下同),在長沙比亞迪汽車城二期興建電動卡車及專用車生產基地,計畫年內投產。   長沙比亞迪專案將由電動轎車、電動客車和電動卡車及專用車三部分組成。電動卡車及專用車專案,現已動工建設,是比亞迪電動卡車及專用車全球製造中心,含整車及相應配套零部件,目標向全中國工廠提供電動底盤、車橋等核心部件。比亞迪預計2016年將達產2500輛,規劃至2020年達5000輛年產能,2025年擴建到10000輛年產能。   此外,比亞迪在青島市城陽區投資30億元的新能源汽車專案一期目前已開工建設,這是青島城陽首個新能源汽車產業專案,也是建區以來引進的最大工業專案。根據規劃分三期建設完成,預計2017年全部建成。專案全部建成後,將年產電動汽車5000輛,年可實現銷售收入105億元。   此專案位於棘洪灘軌道交通裝備製造產業園內,規劃佔地1000畝,主要生產純電動轎車、中巴、小巴、物流車等產品,以及從事車輛電池、電機、電控等核心零部件的研發和製造。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益

※教你寫出一流的銷售文案?

比亞迪新能源車夯!2015年可望售出350億人民幣

根據中國汽車工業協會公佈的統計資料顯示,2015年1至4月份,比亞迪新能源汽車銷量已超過1.2萬輛。同時第一季,比亞迪歸屬於上市公司股東的淨利潤達1.2億元人民幣(下同),同比增幅高達910%。   按4月份單月的銷量資料來看,比亞迪乘用車總體銷量為32260輛,年減29.85%。但新能源汽車銷量為3646輛,其中秦2625輛,e6電動車890輛,騰勢131輛,實現了正向增長。   據比亞迪相關人士介紹,2015年,比亞迪還將推出包括鎖定個人消費者的插電式混合動力汽車「唐」,中型及緊湊型插電式混合動力SUV車型「宋」和「元」,以及新能源商用車「商」等。除此之外,在特種車輛方面,比亞迪也會逐步加快研發並推出應用於礦山、港口、機場及倉儲等領域的車型,以及應用於環衛、城市物流等領域的特種車輛。   而比亞迪副總裁廉玉波在出席內地電動車研討會時透露,預料今年可售出約值300億元至350億元的新能源汽車,料全年可售出約6.7萬部新車,佔公司汽車業務一半收入,並有望達到「自給自足」盈利水準。   他表示,現時比亞迪每月可售出1,000部純電動車e6,純電動巴士每月售約600部。且位於惠州的電池廠3月起投產,有利提升產能;其中較受歡迎的混能車「秦」,6月時產能將增至6,000架。而比亞迪與戴姆勒合資生意的純電動車「騰勢」,每月約售出500部,估計年底時將增至3,000至4,000部。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想要讓你的商品成為最夯、最多人討論的話題?網頁設計公司讓你強力曝光

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

新北清潔公司,居家、辦公、裝潢細清專業服務

台達電與福特亮相CES Asia 推新型智慧電動車解決方案

25日,台達電與福特汽車、海爾、天合光能攜手亮相首屆亞洲消費電子展(CES Asia),宣佈將四方聯合打造的「福特智•能生活」專案引入中國市場。此試點專案將在北京和上海兩個城市率先展開。福特及台達等合作夥伴將為試點家庭提供插電式混合動力汽車、智慧型交流充電樁、太陽能動力設備及智慧家電。   台達電在「福特智•能生活」專案中提供智慧型的電動車充電解決方案,並在福特展臺實地展示了壁掛式高效充電器產品。此壁掛式交流充電器已通過CQC/SRRC認證,採用防塵防水及防破壞機身設計,具備電壓、溫度等保護功能。充電器內建RFID讀卡機,可實現充電用戶身份辨識功能。充電器還內置乙太網通訊功能,可與充電站管理系統集成。   台達電動交通及雲端電源方案事業處總經理張育銘表示,福特這項計畫結合太陽能、家電和充電裝置,台達電導入家庭能源管理,讓電動車充電時用電不會超過既有容量,減少跳電的風險。此外,使用台達的充電裝置能遠端遙控,使用者可透過手機應用程式得知車輛是否充飽電,其還可採時間電價控制時程。   張育銘說,在政府補貼下,大陸電動車市場前景看好,未來幾年每年成長至少都有30%至50%。他表示,台達電開發電動車充電裝置近3年,原本就有和福斯(VW)和富豪(Volvo)合作,今年在大陸的交流充電器銷量預計達4000至5000台,遠高於2014年的數百台。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

※幫你省時又省力,新北清潔一流服務好口碑

※別再煩惱如何寫文案,掌握八大原則!

用Visual C++創建WPF項目的三種主要方法

用Visual C++創建WPF項目的三種主要方法

The problem with using XAML from C++

Because C++ doesn’t support partial class definitions, it isn’t possible to directly support XAML in VC++ projects using this mechanism. That isn’t, however, the core reason why VC++ doesn’t directly support XAML. In addition to using the x:Class attribute, you can also use the x:Subclass attribute so that the XAML gets compiled into the class specified by the x:Class attribute, and the code behind will define the class specified by x:Subclass, which will be derived from the x:Class type. Thus, the lack of partial classes isn’t that big of a block. The main issue is that, right now, no 100-percent CodeDOM support is available to convert

the XAML to C++, and that is the single biggest reason why VC++ doesn’t support XAML intrinsically. I don’t know this for sure, but it’s possible that on a later date, the Visual C++ team may work on their CodeDOM support and provide a fully functional XAML-to-C++ converter. Once that’s available, XAML support can be integrated into VC++ projects. As of today, however, that isn’t an option.

NOTE: CodeDOM is a term used to represent a bunch of types available in the System.

CodeDom namespace that lets you abstract code into an object model. Source code is represented using the CodeDOM tree and can be converted into source code for a specific language using the CodeDOM code generator for that specific language.

Still, the fact that you can’t directly use XAML in a Visual C++ project doesn’t mean that WPF applications can’t be written with Visual C++.

Three ways to write WPF apps using VC++

You can use three different approaches to write WPF applications using Visual C++. Each has its pros and cons, and we’ll cover each of these approaches in the next section:

  • Use procedural code.

For one thing, you can directly use procedural code to

write Avalon-based applications and avoid using XAML. Of course, if you

do that, you automatically give up the advantages of declarative programming

that XAML brings in, but for certain scenarios, procedural code often

serves the purpose well.

  • Dynamically load XAML.

Alternatively, you can dynamically load XAML during runtime to create your Avalon windows, although the disadvantage is that you’d be distributing a bunch of XAML files with your application.

  • Derive from a class in a C# DLL

A third technique uses a C# project to create your XAML-based Avalon controls and have a class (or classes) in your C++ project that derives from the classes in the C#-based Avalon DLL. With that mechanism, the UI is created using XAML in the C# project, and the business logic is kept in the C++ project.

When you’re developing WPF applications with C++, you can use one or more of these approaches to achieve whatever functionality you want. In the next section, you’ll see how to write a simple WPF app with C++/CLI using each of the three techniques mentioned here.

7.2 Using C++/CLI to write a WPF application

If Visual C++ doesn’t have support for XAML, and there are no project templates for building an Avalon application (as of the June 2006 CTP), how much extra effort does it take to write Avalon applications using C++? In this section, you’ll find out. You’ll put the three different techniques I described at the end of section

7.1.2 into action. All three mechanisms have their advantages and disadvantages; you can decide which is most suitable for your specific scenario. First, though, let’s briefly go over how to create a new C++/CLI project for Avalon.

7.2.1 Creating a new C++/CLI Avalon project

Avalon is a managed framework, and as such any Visual C++ project that needs to access and use Avalon needs to have the /clr compilation mode turned on.

Creating a new C++/CLI project with support for Avalon is fortunately not a difficult task. Table 7.1 lists the few simple steps you need to follow each time you create an application (or library, as the case might be) that uses Avalon.

Table 7.1 Steps to create a C++/CLI Avalon project

Step Action How To
1 Generate a new project Using the application wizard, specify the CLR Empty Project template.
2 Set the SubSystem to /SUBSYSTEM:WINDOWS Apply this change in the Project properties, Linker settings, System sub-setting.
3 Set the Entry Point to main From Project properties, choose Linker settings and then the Advanced sub-setting.
4 Add references to the following assemblies: System PresentationCore PresentationFramework WindowsBase Note: Except for System, the other three are required for Avalon.

At this point, your empty project is ready for writing Avalon code. Of course, you don’t have any code yet to compile, but you’ll fix that soon.

7.2.2 Using procedural code

You’ll now write your first Avalon application using C++/CLI, and you’ll do so entirely using procedural code. Think of it as analogous to an instruction book for putting together a table that contains only textual instructions (analogous to the procedural code) and no pictures (analogous to the XAML).

Create a new CLR project using the steps outlined in the previous section, and add an App.cpp file to it (you can call it whatever you want). Listing 7.2 shows the code for the simplest Avalon application that shows a window onscreen.

Listing 7.2 A simple Avalon app in procedural code

If you compile and run the application, you’ll see a window onscreen that can be moved, resized, minimized, maximized, and closed. Avalon requires you to set the COM threading model to single threaded apartment (STA). You do so using the STAThread attribute on the main function . You then create a new instance of the Application object (using gcnew) and invoke the Run method on that instance, passing in a new instance of a Window object (again using gcnew) . The Application class represents an Avalon application and provides the core functionality for running the application. It has a Run method that is called to initiate the application’s main thread. The Run method has an overload that accepts a Window object, which you use in the code. This overload launches the application and uses the specified Window as the main application window. The Window class represents the core functionality of a window and by default provides you with basic windowing functionality such as moving, resizing, and so on, which you verified when you ran the application and saw a fully functional window onscreen.

Note: Those of you who have an MFC background may see a faint similarity between this model and MFC, where the CWinApp class is analogous to the Application class, and the CFrameWnd class is analogous to the Window

class. CWinApp has a Run method that provides the default message loop, and Application::Run does something similar. Of course, you shouldn’t infer too much from these minor similarities because they’re totally different UI programming models, but it’s possible that a similar design model was used by the architects of Avalon.

This little program doesn’t have a lot of functionality; it just uses the default Window object to create and show a window onscreen. Let’s write a more refined application with its own Application-derived object as well as a window with some controls. Figure 7.4 shows a screenshot of what the enhanced application

will look like.

The main steps involved would be to derive two classes-one from the Window class, and the other from the Application class. You’ll start with the Window-derived class.

Figure 7.4

Enhanced WPF app in C++ (procedural code)

Writing the Window-derived class

The first thing you’ll do is add a new class called FirstWindow to your project, which will be derived from the Window class. You’ll also add some member variables for the various controls and set some of the window properties in the constructor. Listing 7.3 shows the code once you’ve done that.

Listing 7.3 A more functional Avalon app in procedural code

using namespace System;

using namespace System::Windows;

using namespace System::Windows::Controls;

It’s much like Windows Forms programming, except that the controls you declare ①. are from the System::Windows::Controls namespace (which contains various WPF controls). You set properties like Title, Width, Height, and so on on the window object in the constructor ②. There’s also a call to a method called InitControls ③, where you initialize the child controls (I put it into a separate method to improve the code’s readability). Listing 7.4 shows the InitControls method. Basically, you instantiate each of the child controls, instantiate a container control, add the child controls to the container controls, and finally set the container control as the main Content of the parent window.

Listing 7.4 Function to initialize the Avalon controls

void InitControls(void)

{
      listbox = gcnew ListBox();
      listbox->Width = 180;

      listbox->Height = 350;

      Canvas::SetTop(listbox, 10);

      Canvas::SetLeft(listbox, 10);

      textbox = gcnew TextBox();

      textbox->Width = 180;

      textbox->Height = 25;
    
      Canvas::SetTop(textbox, 10);

      Canvas::SetLeft(textbox, 200);

      addbutton = gcnew Button();

      addbutton->Width = 80;

      addbutton->Height = 25;

      addbutton->Content = "Add";

      Canvas::SetTop(addbutton, 45);

      Canvas::SetLeft(addbutton, 200);

      addbutton->Click += gcnew RoutedEventHandler(this, &FirstWindow::OnAddButtonClick);

      maincanvas = gcnew Canvas();

      maincanvas->Children->Add(listbox);

      maincanvas->Children->Add(textbox);

      maincanvas->Children->Add(addbutton);

      Content = maincanvas;
}

Again, you probably notice the similarity with Windows Forms programming.

You instantiate the child controls ①, ②, and ③, and set various properties like Width and Height, and you also use the Canvas::SetTop and Canvas::SetLeft methods to position them on their container. For the button control, you also add an event handler for the Click event ④. Then, you instantiate the Canvas control (which is a container control for other child controls) and add the child controls as its children ⑤. Finally, you set the Content property of the window to this Canvas control ⑥.

Now, you need to add the Click event handler for the button control, where you add the text entered into the TextBox to the ListBox:

void OnAddButtonClick(Object^ sender, RoutedEventArgs^ e)
{
​	listbox->Items->Add(textbox->Text);
​	textbox->Text = "";
​	textbox->Focus();
}

Notice that you set the text of the TextBox to an empty string once you’ve added it to the ListBox. You also call the Focus() method so that the user can continue

adding more entries into the ListBox. The Window-derived class is ready. Let’s now write the Application-derived class.

Writing the Application-derived class

You derive a class called FirstApp from Application and add an override for the OnStartup method where you create and show the main window:

#include "FirstWindow.h"

ref class FirstApp : Application
{
public:
FirstApp(void){}

protected:
      virtual void OnStartup(StartupEventArgs^ e) override
      {
          Application::OnStartup(e);
          FirstWindow^ mainwnd = gcnew FirstWindow();
          mainwnd->Show();
      }
};

The OnStartup method is called, not surprisingly, when the application has just started. You override that function so that you can instantiate and show the window.

The base function is responsible for invoking any event handlers associated with the Startup event, and thus you need to call the base method in the override.

Now, all that’s left is to modify the main function to use the custom Application object instead of the default, as shown here:

#include "FirstApp.h"

[STAThread]

int main(array<String^>^ args)
{
	return (gcnew FirstApp())->Run();
}

Notice that you don’t specify a window object to the Run method, because the window object is created in the OnStartup override of your Application-derived class.

Compile and run the application, and try entering some text into the TextBox and clicking the Add button. You should see the text being entered into the ListBox.

When you use procedural code with Avalon, it’s much like using Windows Forms, where you derive classes from the default controls, set some properties, add some event handlers, and are done. Procedural code is all right to develop WPF applications for simple user interfaces, but sometimes it makes better sense

to take advantage of XAML and declarative programming. As I’ve mentioned a few times already, XAML isn’t directly supported in VC++, so you’ll have to look at alternate options to make use of XAML. One such option is to dynamically load the XAML at runtime.

7.2.3 Dynamically loading XAML

In this section, you’ll rewrite the application you wrote in the previous section, using dynamically loaded XAML. This way, you get to leverage the power of XAML and declarative programming (which you couldn’t in the procedural code technique you used in the previous section). Continuing the instruction-book analogy, this will be like one that has textual instructions that refer to pictures (which describe the various steps needed) and are loosely distributed along with the book but not directly printed in the book. You’ll define the UI using XAML instead of procedural code. When you’re done, you’ll have an identical application

to the one you previously created.

Create a new C++/CLI Avalon project using the steps mentioned in the introduction to section 7.2, and call it FirstAvalonDynamic (or whatever you want to call it). The first thing you’ll do is write the XAML (MainWindow.xaml) that represents the UI; see listing 7.5.

Listing 7.5 XAML for the main window

<Window

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

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

     Title="First Avalon App (dynamically load XAML)"

     Height="400" Width="400"

     ResizeMode="NoResize"

     > 

     <Canvas>
           <ListBox Canvas.Left="10" Canvas.Top="10"
                 Width="180" Height="350"
                 Name="listbox" />
               <TextBox Canvas.Left="200" Canvas.Top="10"
                 Width="180" Height="25"
                 Name="textbox" />
           <Button Canvas.Left="200" Canvas.Top="45"
                 Width="80" Height="25"
                 Name="addbutton">Add</Button>
     </Canvas>
</Window>

The XAML shown does exactly what you did with the procedural code earlier. For the control elements, you use the same names using the Name attribute as you use for the member variables in the procedural code. Next, you need to hook an event handler to the Button so that the text entered into the TextBox is inserted

into the ListBox. For that, you’ll write a helper class, as shown in listing 7.6.

Listing 7.6 WindowHelper class that implements the event handler

using namespace System;

using namespace System::Windows;

using namespace System::Windows::Controls;

using namespace System::Windows::Markup;

using namespace System::IO;

ref class WindowHelper
{

     ListBox^ listbox;

     TextBox^ textbox;

     Button^ addbutton;



public:
WindowHelper(Window^ window)
{
   addbutton = (Button^)window->FindName("addbutton");

   textbox = (TextBox^)window->FindName("textbox");

   listbox = (ListBox^)window->FindName("listbox");

   addbutton->Click += gcnew RoutedEventHandler(

   this,&WindowHelper::OnAddButtonClick);
}

void OnAddButtonClick(Object^ sender, RoutedEventArgs^ e)
{
   listbox->Items->Add(textbox->Text);

   textbox->Text = "";

   textbox->Focus();
}

};

The WindowHelper constructor accepts a Window argument and uses the FindName method ① to get the control with the specified identifier (which maps to the Name attributes you used in the XAML). You also hook an event handler to the addbutton control ②. Finally, you have the event handler③, which is identical to the one you used in the procedural code project. Listing 7.7 shows the code for the Application-derived class, where you override OnStartup as before, except that you create a window dynamically by loading the XAML file from the disk.

Listing 7.7 The Application-derived class

ref class FirstAppDynamic : Application

{

public:

     FirstAppDynamic(void)
     {

     }

protected:
     virtual void OnStartup(StartupEventArgs^ e) override
     {

           Application::OnStartup(e);

           Stream^ st = File::OpenRead("MainWindow.xaml");

           Window^ mainwnd = (Window^)XamlReader::Load(st);

           st->Close();

           WindowHelper^ mainwndhelper = gcnew WindowHelper(mainwnd);

           mainwnd->Show();

     }

};

You open a file stream to the XAML using File::OpenRead ① and use the overload of XamlReader::Load ② that takes a Stream^ as parameter to create a Window object. This Load method works the magic, by reading and parsing the XAML and building a Window object out of it. You instantiate the WindowHelper object and pass

this Window object as the argument, so that the event handler for the addbutton control is properly set up ③. You then show the window ④ with a call to Show().

The main method is much the same as before, where you instantiate the Application object and call Run on it:

[STAThread]
int main(array<String^>^ args)
{

      return (gcnew FirstAppDynamic())->Run();

}

The advantage of using this technique over using procedural code is that you get to design your UI in XAML, thereby achieving a level of UI/code separation. You can also use Cider or some other XAML designer to quickly design flexible user interfaces, which would involve a good bit of hand-coding in procedural code.

The disadvantage is that you have to distribute the XAML file with your application, and if you have multiple windows, you then need that many XAML files.

There’s always the risk of a loosely-distributed XAML file getting corrupted (accidentally or otherwise) or even being deleted. You can embed all the XAML files as resources in the C++/CLI assembly and load them at runtime, but even that involves a lot of extra work. To avoid distributing XAML files loosely with your

application or embedding them as resources, you may want to use the technique we’ll discuss in the next section: putting the XAML into a C# project and accessing it via a derived class in a C++ project.

7.2.4 Deriving from a class in a C# DLL

You’ll write a third variation of the same application in this section. You’ll use a C# control library project for the XAML, and a C++ project that will utilize that XAML control by deriving a control from it. Using the instruction-book analogy again, this is essentially a picture-based, step-by-step guide with the textual

instructions printed alongside each picture providing some meta-information for the step indicated by that picture. First, use the New Project Wizard to generate a new C# .NET 3.0 Custom Control Library project, and delete the default XAML file generated by the wizard. The default XAML is derived from User-

Control and isn’t what you want. Add a new XAML file to the C# project that represents a Window, and either use Cider or hand-code the XAML from listing 7.8 into that file.

Listing 7.8 The Window class definition using XAML

<Window x:Class="CSXamlLibrary.BaseWindow"
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     Title="First Avalon App (dynamically load XAML)"
     Height="400" Width="400"
     ResizeMode="NoResize"
     > 

     <Canvas>
           <ListBox Canvas.Left="10" Canvas.Top="10"
                 Width="180" Height="350"
                 Name="listbox" x:FieldModifier="protected" />

           <TextBox Canvas.Left="200" Canvas.Top="10"
                 Width="180" Height="25"
                 Name="textbox" x:FieldModifier="protected" />

           <Button Canvas.Left="200" Canvas.Top="45"
                 Width="80" Height="25"
                 Name="addbutton" x:FieldModifier="protected">Add</Button>
     </Canvas>

</Window>

The XAML is identical to that used in the previous project (where you dynamically loaded it) except for the x:Class attribute for the Window element, which specifies the name of the class that will be generated, and the x:FieldModifier attributes that are applied to the child control elements so they’re generated as protected members in the class (rather than as private which is the default). Build the C# project, and generate the control library. Once that’s done, create a new C++/CLI Avalon project (using the same steps as before), and then add a reference to this C# project. Now, you can write a new Window class that’s derived from the class in the C# DLL, as shown in listing 7.9.

Listing 7.9 Deriving the main window from the XAML-defined Window class

using namespace System;

using namespace System::Windows;

using namespace System::Windows::Controls;



ref class AppMainWindow : CSXamlLibrary::BaseWindow
{
     public:
           AppMainWindow(void)
           {
                 addbutton->Click += gcnew RoutedEventHandler(this, &AppMainWindow::OnAddButtonClick);
           }

           void OnAddButtonClick(Object^ sender, RoutedEventArgs^ e)
           {

                 listbox->Items->Add(textbox->Text);

                 textbox->Text = "";

                 textbox->Focus();

           }

};

The code is similar to what you’ve seen thus far, except that it’s a lot cleaner.

Unlike the first example, you don’t have a lot of clogged procedural code to create the UI. Unlike the second example, you don’t need a helper class to map the XAML elements to the control variables and event handlers. It’s definitely an improvement over the previous two examples, but you have to bring in the C#

project just for the XAML. The rest of the code needed for the application is more or less similar to what you saw earlier:

ref class FirstAppDerived : Application
{
      protected:
            virtual void OnStartup(StartupEventArgs^ e) override
            {
                  Application::OnStartup(e);
                  AppMainWindow^ mainwnd = gcnew AppMainWindow();
                  mainwnd->Show();
            }

};

[STAThread]

int main(array<String^>^ args)
{
      return (gcnew FirstAppDerived())->Run();
}

In some ways, the third technique is a sort of hybrid of the previous two techniques.

A lot of the code is identical to that in the first technique – as with the declaration of a custom class derived from Window and an Application-derived class with the OnStartup method creating the custom window. But, like the second technique, the UI definition is in the XAML, except that in this case, it’s compiled into the C# DLL. You also reduce lines of code with each successive technique. You had the most lines of code with procedural code (as is to be expected) and improved on that considerably when you moved the UI definition to the XAML in the dynamically-loaded XAML example. In the last example, you saved even further on lines of code, such as the helper class from the second example that had to wire the XAML elements to the member variables. Of course, the total lines of code (LOC) isn’t always the single deciding factor that determines what technique you choose. Table 7.2 shows a comparison of the three techniques; for each factor, the cells with the bold text reflect the technique (or techniques) that offer maximum performance (or convenience).

Table 7.2 Comparison of the three techniques

Procedural code Dynamically load XAML XAML in C# DLL
Cluttered code that generates the UI Yes No No
Dependency on loose XAML files No Yes No
Dependency on C#-based DLL No No Yes
Lines of code Maximum In-between Minimum
UI design convenience Poor Excellent Excellent
UI/business logic separation Poor Good Excellent
Level of Visual C++ project support Total Partial (Not applicable)

It’s hard to pinpoint a specific technique and claim that it’s the best one, because depending on your requirements, each has advantages and disadvantages. Of course, in the future, if Visual C++ has direct support for XAML (as I believe it will), that will be your best option for the majority of scenarios.

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益

※教你寫出一流的銷售文案?