开始学习WPF
前天(2008年4月2日)在當當網(wǎng)購買了一本書:
《Windows Presentation Foundation 程序設(shè)計指南》
[美]Charles Petzold 著,蔡學(xué)鏞 譯,胡志鵬、魏顥、成功 審校
ISBN: 978-7-121-05115-9,電子工業(yè)出版社,2008年1月第1次印刷
Applications = Code + Markup: A Guide to the Microsoft Windows Presentation Foundation
ISBN: 0-7356-1957-3; Microsoft Press; August 2006; 1002 pages
Errata: http://www.charlespetzold.com/wpf/errata.xml
于是就開始了WPF學(xué)習之旅。
這本書英文原作寫得相當好,中文翻譯也很好。英文原作是2006年8月出版的,中譯本是在2008年1月出版的,出得有點遲了,而且不知為什么中譯本出版時沒有按照英文版的勘誤表進行更正(倒是有好幾處審校者的質(zhì)疑,其實都是英文版的勘誤表中已經(jīng)更正過的)。
目前發(fā)現(xiàn)的錯誤(不斷更新中...):
第190頁,倒數(shù)第2自然段中間:
如果 Stretch 等于 Stretch.Uniform(默認),MeasureOverride 會利用 sizeAvailable 參數(shù)計算出正確的長寬比,并維持這樣的比例,且讓一個維度(寬或高)等于 sizeAvialable 的 Width 或 Height。
英文原文是:
For Stretch.Uniform(the default setting), MeasureOverride uses the sizeAvailable argument to calculate a size that maintains the correct aspect ratio but has one dimension equaling either the Width or Height dimension of sizeavailable.
我認為應(yīng)該這樣翻譯:
如果 Stretch 等于 Stretch.Uniform(這是默認值),MeasureOverride 會利用 sizeAvailable 參數(shù)計算出一個尺寸,該尺寸保持正確的長寬比,且讓一個維度(寬或高)等于 sizeAvailable 的 Width 或 Height。
第219頁,程序代碼之后的第2自然段,第1句:
除了 override FrameworkElement 與 Control,建立自定義的控件還有別的方式,使用 XAML 比使用代碼的方式更常見,利用樣本的定義達到此目的。
英文原文是:
Besides overriding FrameworkElement and Control, there is another approach to creating custom controls that is used much more in XAML than in procedural code. This is through the definition of a template.
我認為應(yīng)該這樣翻譯:
除了 override FrameworkElement 與 Control,建立自定義的控件還有別的方式,使用 XAML 比使用代碼的方式更常見,就是通過定義一個模板來達到此目的。
第235頁,第2自然段,第2句:
Panel 最大的好處是,它有 Children Property 可以進行孩子的排序。
英文原文是:
The big gift of Panel is the definition of Children property for storing the children.
我認為應(yīng)該這樣翻譯:
Panel 最大的好處是,它有一個用來存儲孩子們的 Children 屬性。
第239頁,第5自然段之后,漏了以下一個自然段:
In other words, the grid is behaving as we might hope and expect. To further test it, dig out the ColorGrid control from the last chapter and replace UniformGrid with UniformGridAlmost.
換句話說,grid 的行為可能符合我們的期望和預(yù)期。為了進一步測試它,找出上一章的 ColorGrid 控件,并且將其中的所有 UniformGrid 都替換為 UniformGridAlmost。
第451頁,NotePadClone.Help.cs 程序,中間位置:
? itemHelp.SubmenuOpened += ViewOnOpen;
這條語句應(yīng)該刪除(英文原版中就錯了)。
第466頁,第1句:
構(gòu)造函數(shù)為此 XML 資源建立一個 Uri 對象,然后使用靜態(tài)的 Application.GetResourceStream property,取得一個 StreamResourceInfo 對象。
這句話是英文原文的錯誤,不是譯者的翻譯錯誤。這句話應(yīng)該是這樣的:
構(gòu)造函數(shù)為此 XML 資源建立一個 Uri 對象,然后調(diào)用靜態(tài)的 Application.GetResourceStream 方法,取得一個 StreamResourceInfo 對象。
第468頁,第1自然段,第2句:
你可以使用此程序,加載本章至今的任何 XAML 文件(擴展名是 .xml)。
英文原文是:
You can use this program to load any of the XAML files shown is this chapter so far, including those with a file name extension of .xml.
我認為應(yīng)該這樣翻譯:
你可以使用此程序,加載本章至今的任何 XAML 文件,包括那些擴展名是 .xml 的文件。(譯者注:XAML 文件默認的擴展名是 .xaml)
第490頁,XamlCruncher.cs 程序,中間位置:
????? split = new GridSplitter();
????? split.HorizontalAlignment = HorizontalAlignment.Center;
????? split.VerticalAlignment = VerticalAlignment.Stretch;
????? split.Height = 6;
????? grid.Children.Add(split);
????? Grid.SetRow(split, 0);
????? Grid.SetColumn(split, 1);
????? Grid.SetRowSpan(split, 3);
應(yīng)改為(英文原版中就錯了,但該書網(wǎng)站上提供下載的源程序代碼是正確的):
????? split = new GridSplitter();
????? split.HorizontalAlignment = HorizontalAlignment.Center;
????? split.VerticalAlignment = VerticalAlignment.Stretch;
????? split.Width = 6;
????? grid.Children.Add(split);
????? Grid.SetRow(split, 0);
????? Grid.SetColumn(split, 1);
????? Grid.SetRowSpan(split, 3);
第512頁,最后1自然段(除了程序代碼以外):
然而,GradientStops property 必須變成一個 property element:
英文原文是:
The GradientStops property is of type GradientStopCollection, so we can put in an object element for that class:
我認為應(yīng)該這樣翻譯:
GradientSopts property 的類型是 GradientStopCollection,于是我們可以將其放到一個 object element 中:
第525頁,程序代碼之后的第1自然段:
注意 StackPanel element tag 定義了一個 XML 命名空間的前綴 s,代表 System 命名空間(clr-namespace:System;assembly=mscorlib),這允許引用此 Resources collection 中的 Double 結(jié)構(gòu)。
英文原文是:
Notice that the StackPanel element tag defines an XML namespace prefix of s for the System namespace (clr-namespace:System;assembly=mscorlib), which allows referencing the Double structure in the Resources collection.
我認為應(yīng)該這樣翻譯:
注意 StackPanel element tag 定義了一個 XML 命名空間的前綴 s,代表 System 命名空間(clr-namespace:System;assembly=mscorlib),這允許在此 Resources collection 中引用 Double 結(jié)構(gòu)。
第569頁,程序代碼之后的第1自然段,第2句:
然而,Page2 類沒有這一關(guān)鍵的 Navigate 方法,可以用于直接訪問 NavigationWindow 對象。
英文原文是:
However, the Page2 class doesn't have direct access to the NavigationWindow object with that crucial Navigate method.
我認為應(yīng)該這樣翻譯:
然而,Page2 類無法直接訪問 NavigationWindow 對象,該對象具有關(guān)鍵的 Navigate 方法。
第571頁,最后1自然段,第2句:
但是這里還有一個有趣的實驗:在 FrameNavigationDemoWindow.xaml 中,將 Window 改成 NavigationWindow,然后重新編譯。
這句話有問題,建議改為:
但是這里還有一個有趣的實驗:在 FrameNavigationDemoWindow.xaml 中,將 Window 改成 NavigationWindow,并添加一個 NavigationWindow.Content property element,然后重新編譯。
第584頁底部到第585頁頂部,DirectoryPage.xaml 源代碼:
DirectoryPage.xaml <!-- ================================================
????? DirectoryPage.xaml (c) 2006 by Charles Petzold
???? ================================================ -->
<PageFunction xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
????????????? xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
????????????? xmlns:io="clr-namespace:System.IO;assembly=mscorlib"
????????????? xmlns:tree="clr-namespace:Petzold.RecurseDirectoriesIncrementally"
????????????? x:Class="Petzold.ComputerDatingWizard.DirectoryPage"
????????????? x:TypeArguments="io:DirectoryInfo">
? <Grid>
??? <Grid.RowDefinitions>
????? <RowDefinition Height="Auto" />
????? <RowDefinition Height="*" />
????? <RowDefinition Height="Auto" />
??? </Grid.RowDefinitions>
??? <TextBlock Grid.Row="0" FontSize="16" FontStyle="Italic"
?????????????? HorizontalAlignment="Center">
????? Computer Dating Wizard
??? </TextBlock>
??? <tree:DirectoryTreeView x:Name="treevue" Grid.Row="1" />
??? <!-- Buttons at bottom-right corner of page. -->
??? <Grid Grid.Row="2">
????? <Grid.ColumnDefinitions>
??????? <ColumnDefinition Width="*" />
??????? <ColumnDefinition Width="Auto" />
??????? <ColumnDefinition Width="Auto" />
????? </Grid.ColumnDefinitions>
????? <Button Grid.Column="1" Click="CancelButtonOnClick"
????????????? IsCancel="True" MinWidth="60" Margin="6">
??????? Cancel
????? </Button>
????? <Button Grid.Column="2" Name="btnOk" Click="OkButtonOnClick"
????????????? IsEnabled="False" IsDefault="True" MinWidth="60" Margin="6">
??????? OK
????? </Button>
??? </Grid>
? </Grid>
</PageFunction>
應(yīng)改為:
DirectoryPage.xaml <!-- ================================================
????? DirectoryPage.xaml (c) 2006 by Charles Petzold
???? ================================================ -->
<PageFunction xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
????????????? xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
????????????? xmlns:io="clr-namespace:System.IO;assembly=mscorlib"
????????????? xmlns:tree="clr-namespace:Petzold.RecurseDirectoriesIncrementally"
????????????? x:Class="Petzold.ComputerDatingWizard.DirectoryPage"
????????????? x:TypeArguments="io:DirectoryInfo">
? <Grid>
??? <Grid.RowDefinitions>
????? <RowDefinition Height="*" />
????? <RowDefinition Height="Auto" />
??? </Grid.RowDefinitions>
??? <tree:DirectoryTreeView x:Name="treevue" Grid.Row="0" />
??? <!-- Buttons at bottom-right corner of page. -->
??? <Grid Grid.Row="1">
????? <Grid.ColumnDefinitions>
??????? <ColumnDefinition Width="*" />
??????? <ColumnDefinition Width="Auto" />
??????? <ColumnDefinition Width="Auto" />
????? </Grid.ColumnDefinitions>
????? <Button Grid.Column="1" Click="CancelButtonOnClick"
????????????? IsCancel="True" MinWidth="60" Margin="6">
??????? Cancel
????? </Button>
????? <Button Grid.Column="2" Name="btnOk" Click="OkButtonOnClick"
????????????? IsEnabled="False" IsDefault="True" MinWidth="60" Margin="6">
??????? OK
????? </Button>
??? </Grid>
? </Grid>
</PageFunction>
下面是修改前后程序運行的屏幕截圖:
?
第585頁,程序代碼之后的第1自然段,倒數(shù)第2句:
另一個命名空間的聲明關(guān)聯(lián)起“tree”前綴和第16章 RecurseDirectoriesIncrementally 工程的命名空間。
這句話后面漏了一句:
That's where the DirectoryTreeView class comes from that forms the bulk of this page.
我認為應(yīng)該這樣翻譯:
另一個命名空間的聲明關(guān)聯(lián)起“tree”前綴和第16章 RecurseDirectoriesIncrementally 工程的命名空間。而 RecurseDirectoriesIncrementally 命名空間正是此頁面主體部分的 DirectoryTreeView 類所在的命名空間。
第586頁,程序代碼之后的第1自然段,第1句:
構(gòu)造函數(shù)為 DirectoryTree 控件設(shè)置 ViewSelectionChanged 事件處理函數(shù),好讓 OK 按鈕“只有在磁盤驅(qū)動器目錄被選取的情況下”才會被 enable。
英文原文是(這句話中的“SelectionChanged”應(yīng)該是“SelectedItemChanged”):
The constructor attaches a SelectionChanged event handler to the DirectoryTreeView control so that the OK button is enabled only if a disk directory has been selected.
這認為應(yīng)該這樣翻譯:
構(gòu)造函數(shù)為 DirectoryTreeView 控件設(shè)置 SelectedItemChanged 事件處理函數(shù),好讓 OK 按鈕“只有在磁盤驅(qū)動器目錄被選取的情況下”才會被 enable。
第594頁,程序代碼之后的第1自然段,第1句:
這兩個 Hyperlink element 包含的不只是 NaviagateUri attribute (引用兩個 XML 文件),也包含了 TargetName attribute (引用 BookList.xaml 頁面上方的 Frame)。
英文原文是(這句話中的“BookList.xaml”應(yīng)該是“BookReader.xaml”):
The two Hyperlink elements contain not only NavigateUri attributes that reference two XAML files, but also TargetName attributes that reference the Frame at the left of the BookList.xaml page.
我認為應(yīng)該這樣翻譯:
這兩個 Hyperlink element 包含的不只是 NaviagateUri attribute (引用兩個 XML 文件),也包含了 TargetName attribute (引用 BookReader.xaml 頁面左邊的 Frame)。
第600頁,第1句:
WindowOnLoaded 事件處理函數(shù)會用 Tile 對象和 Empty 對象來為 UniformGrid 初始化。
應(yīng)該改為(這句話英文原文就是錯的):
PageOnLoaded 事件處理函數(shù)會用 Tile 對象和 Empty 對象來為 UniformGrid 初始化。
第607頁,程序代碼之后的第1自然段最后2句:
大多數(shù)情況下 Label.Content tag 不是必須的,你可以試著移除它。但是在這里,確實是必要的。
經(jīng)實驗,在這里,Label.Content tag 也不是必須的。也就是說,我試著移除它,程序照正常工作。
第609頁,最后1自然段,第1句:
現(xiàn)在 ScrollBar 的目標是由 Label 源來控制。
英文原文是:
Now the ScrollBar target is governing the Label source.
我認為應(yīng)該這樣翻譯:
現(xiàn)在 ScrollBar 目標控制 Label 源。
第612頁,除了程序代碼這外的第3個自然段(在該頁正中間):
這段 XAML 在我看起來好像沒問題,但卻拋出一個異常,告訴我“類型為‘System.Windows.Data.Binding’的對象無法轉(zhuǎn)換成‘System.String’”,這里顯然指的是 Text property 的類型。此消息對我來說非常奇怪,因為它言下之意是解析器正在忽略這個再自然不過的數(shù)據(jù)綁定定義。
在我的計算機上,拋出的異常是:不能在類型“Run”的“Text”屬性上設(shè)置“Binding”。只能在 DependencyObject 的 DependencyProperty 上設(shè)置“Binding”。
這個異常消息再正常不過了。我想本書作者看到的奇怪的異常消息可能是他使用 CTP 版本的 WPF 軟件的緣故。
第615頁,程序代碼之后的第2個自然段,第1句:
第一個 ScrollBar 定義一個 OneWayToSource 綁定,其 Number property 是第一個 SimpleElement。
英文原文是:
The first ScrollBar defines a OneWayToSource binding with the Number property of the first SimpleElement.
我認為應(yīng)該這樣翻譯:
第一個 ScrollBar 定義一個 OneWayToSource 綁定,綁定到第一個 SimpleElement 的 Number property。
第615頁,程序代碼之后的第3個自然段,第1句和第2句:
第二個 ScrollBar 定義一個 TwoWay 綁定,其 Number property 是第一個 SimpleElement,且你將會看到這個也順利工作。雖然 SimpleElement 沒有顯式的通知機制 ScrollBar,操作第一個 ScrollBar 產(chǎn)生的 Number property 的改變,會被此綁定檢測到,結(jié)果第二個會跟隨第一個 ScrollBar 變化。
英文原文是:
The second ScrollBar defines a TwoWay binding with the Number property of the first SimpleElement, and you'll see that this one works as well. Although SimpleElement has no explicit notification mechanism, changes to the Number property as a result of manipulating the first ScrollBar are detected in this binding, and the second ScrollBar tracks the first ScrollBar.
我認為應(yīng)該這樣翻譯:
第二個 ScrollBar 定義一個 TwoWay 綁定,綁定到第一個 SimpleElement 的 Number property,且你將會看到這個也順利工作。雖然 SimpleElement 沒有顯式的通知機制,操作第一個 ScrollBar 產(chǎn)生的 Number property 的改變,會被此綁定檢測到,結(jié)果第二個 ScrollBar 會跟隨第一個 ScrollBar 變化。
第615頁,程序代碼之后的第4個自然段,第1句:
第二個 SimpleElement element 定義了一個 OneWay 數(shù)據(jù)綁定。
英文原文是:
The second SimpleElement element defines a OneWay data binding with the second ScrollBar.
我認為應(yīng)該這樣翻譯:
第二個 SimpleElement element 定義了一個 OneWay 數(shù)據(jù)綁定,綁定到第二個 ScrollBar。
第627頁,倒數(shù)第2自然段,最后2句:
然而,有可能你真正需要的是“被此字段 property 所引用的對象”的某個 property。這種情況下,你需要使用綁定。
英文原文是:
However, it's possible that what you really need is a property of the object referenced by the static property. In that case, you need a binding.
我認為應(yīng)該這樣翻譯:
然而,有可能你真正需要的是“被此靜態(tài) property 所引用的對象”的某個 property。這種情況下,你需要使用綁定。
第631頁,從第2自然段開始,到“就這樣”。
原書上這一大段是論述如何定義一個名為 DateTimeChanged 的 public 事件,使用 WPF 數(shù)據(jù)綁定邏輯去更新 DateTime property。但是經(jīng)我實驗,這沒有效果。
第639頁,第4自然段,第1句和2句:
Style 類型定義在 System.Windows 中。其派生自 Object,且沒有子類。
應(yīng)改為(英文原文就是錯的):
Style 類型定義在 System.Windows 中。其派生自 DispatcherObject,且沒有子類。
第646頁,程序代碼之后的第2自然段:
如果你的應(yīng)用中有許多對話框,而這些對話框的 Stack Panel 包含一些 radio buttons (放在 Group box 內(nèi)),為了讓這些 Radio Button 看起來更美觀。RadioButton 的 TargetType 是很好的 Style 范例。
英文原文是:
If you have a bunch of dialog boxes in an application, and these dialog boxes have some radio buttons on stack panels within group boxes, you know you need to apply a Margin property to each RadioButton to make it look reasonably attractive. This is an excellent application of a Style with a TargetType of RadioButton.
我認為應(yīng)該這樣翻譯:
如果你的應(yīng)用中有許多對話框,而這些對話框的 Stack Panel 包含一些 radio buttons (放在 Group box 內(nèi)),為了讓這些 Radio Button 看起來更美觀,你知道需要為每個 Radio Button 應(yīng)用 Margin property。RadioButton 的 TargetType 是很好的 Style 范例。
第652頁,除了程序代碼之外的倒數(shù)第3自然段,第1句:
答案是 Binding 搭配 RelativeSource,這在本章最后會討論到。
英文原文是:
The solution is a Binding using RelativeSource, which I discussed toward the end of the previous chapter.
我認為應(yīng)該這樣翻譯:
答案是 Binding 搭配 RelativeSource,這已經(jīng)在上一章最后討論過。
第656頁,程序代碼之后的第1自然中間:
當 Seal 方法被調(diào)用時,只讀的 IsSeal property 被設(shè)定為 true。
英文原文是:
The read-only IsSealed property becomes true when the Seal method is called, which happpens when the style is in use.
我認為應(yīng)該這樣翻譯:
當 Sytle 被使用時,其 Seal 方法被調(diào)用,只讀的 IsSealed property 被設(shè)定為 true。
第677頁,程序代碼之后的第3自然段,最后1句:
TextBox 與 RichTextBox 控件具有相對簡單的模板,因為這兩個控件其實是 Border element,而 Border 包含 ScrollViewer 控件,ScrollViewer 再包含實際的編輯器,而編輯器則完全使用代碼實現(xiàn)。
這句話英文原文就是這樣,但在我的計算機上通過 DumpControlTemplate 程序卻得到以下結(jié)論:
TextBox 與 RichTextBox 控件具有相對簡單的模板,因為這兩個控件其實是 ListBoxChrome element,而 ListBoxChrome 包含 ScrollViewer 控件,ScrollViewer 再包含實際的編輯器,而編輯器則完全使用代碼實現(xiàn)。
第679頁,除了代碼之外的倒數(shù)第2自然段,第2句:
ContentPresenter 定義了 ContentTemplate property (對象為 DataTemplate),為的是要定義一個“用來顯示內(nèi)容”的模板。
ContentPresenter defines a property named ContentTemplate of type DataTemplate for defining a template used to display content.
我認為應(yīng)該這樣翻譯:
ContentPresenter 定義了 ContentTemplate property (類型為 DataTemplate),為的是要定義一個“用來顯示內(nèi)容”的模板。
第680頁,程序代碼之后的第2自然段,最后1句:
此 UniformGrid 包含一個 TextBlock (用來顯示雇員的名稱)和一個 StackPanel (具有兩個 TextBlock element,用來顯示雇員的生日)。
The UniformGrid has a TextBlock for the employee's name and then a StackPanel with six TextBlock elements that effectively format the employee's birth date.
我認為應(yīng)該這樣翻譯(英文原文誤為“six”):
此 UniformGrid 包含一個 TextBlock (用來顯示雇員的名稱)和一個 StackPanel (具有五個 TextBlock element,用來顯示雇員的生日)。
第694頁,第2自然段,第1句:
下面的 Resource section,先定義控件的 layout。
英文原文是:
Following the Resources section, the definition of the layout of the control begins.
我認為應(yīng)該這樣翻譯:
在 Resources section 之后,先定義控件的 layout。
第699頁,DatePicker.cs 程序代碼,最后一段:
??? // Buttons are duplicated by PageDown and PageUp keys.
??? protected override void OnPreviewKeyDown(KeyEventArgs args)
??? {
????? base.OnKeyDown(args);
????? if (args.Key == Key.PageDown)
????? {
??????? FlipPage(true);
??????? args.Handled = true;
????? }
????? else if (args.Key == Key.PageUp)
????? {
??????? FlipPage(false);
??????? args.Handled = false;
????? }
??? }
應(yīng)改為(英文原版就是錯的):
??? // Buttons are duplicated by PageDown and PageUp keys.
??? protected override void OnPreviewKeyDown(KeyEventArgs args)
??? {
????? base.OnPreviewKeyDown(args);
????? if (args.Key == Key.PageDown)
????? {
??????? FlipPage(true);
??????? args.Handled = true;
????? }
????? else if (args.Key == Key.PageUp)
????? {
??????? FlipPage(false);
??????? args.Handled = true;
????? }
??? }
第705頁,除了程序代碼之外的第4自然段:
XPath property 是一個 XML Path Language 字符串。關(guān)于 XML Path Language,你可以在 www.w3.org/TR/xpath 看到它的文件。
英文原文是:
The XPath property is a string defined in XML Path Language as documented at www.w3.org/TR/xpath, except that no functions are allowed.
我認為應(yīng)該這樣翻譯:
XPath property 是一個 XML Path Language 字符串(除了不支持 XPath 函數(shù))。關(guān)于 XML Path Language,你可以在 www.w3.org/TR/xpath 看到它的文檔。
第738頁,程序代碼中部(NavigationBar.cs),應(yīng)改為(其中紅色的一對大括號是新增的。英文原版就錯了):
??? void TextBoxOnLostFocus(object sender, KeyboardFocusChangedEventArgs args)
??? {
????? int current;
????? if (Int32.TryParse(txtboxCurrent.Text, out current))
????? {
??????? if (current > 0 && current <= coll.Count)
????????? collview.MoveCurrentToPosition(current - 1);
????? }
????? else
??????? txtboxCurrent.Text = strOriginal;
??? }
《Windows Presentation Foundation 程序設(shè)計指南》
[美]Charles Petzold 著,蔡學(xué)鏞 譯,胡志鵬、魏顥、成功 審校
ISBN: 978-7-121-05115-9,電子工業(yè)出版社,2008年1月第1次印刷
Applications = Code + Markup: A Guide to the Microsoft Windows Presentation Foundation
ISBN: 0-7356-1957-3; Microsoft Press; August 2006; 1002 pages
Errata: http://www.charlespetzold.com/wpf/errata.xml
于是就開始了WPF學(xué)習之旅。
這本書英文原作寫得相當好,中文翻譯也很好。英文原作是2006年8月出版的,中譯本是在2008年1月出版的,出得有點遲了,而且不知為什么中譯本出版時沒有按照英文版的勘誤表進行更正(倒是有好幾處審校者的質(zhì)疑,其實都是英文版的勘誤表中已經(jīng)更正過的)。
目前發(fā)現(xiàn)的錯誤(不斷更新中...):
第190頁,倒數(shù)第2自然段中間:
如果 Stretch 等于 Stretch.Uniform(默認),MeasureOverride 會利用 sizeAvailable 參數(shù)計算出正確的長寬比,并維持這樣的比例,且讓一個維度(寬或高)等于 sizeAvialable 的 Width 或 Height。
英文原文是:
For Stretch.Uniform(the default setting), MeasureOverride uses the sizeAvailable argument to calculate a size that maintains the correct aspect ratio but has one dimension equaling either the Width or Height dimension of sizeavailable.
我認為應(yīng)該這樣翻譯:
如果 Stretch 等于 Stretch.Uniform(這是默認值),MeasureOverride 會利用 sizeAvailable 參數(shù)計算出一個尺寸,該尺寸保持正確的長寬比,且讓一個維度(寬或高)等于 sizeAvailable 的 Width 或 Height。
第219頁,程序代碼之后的第2自然段,第1句:
除了 override FrameworkElement 與 Control,建立自定義的控件還有別的方式,使用 XAML 比使用代碼的方式更常見,利用樣本的定義達到此目的。
英文原文是:
Besides overriding FrameworkElement and Control, there is another approach to creating custom controls that is used much more in XAML than in procedural code. This is through the definition of a template.
我認為應(yīng)該這樣翻譯:
除了 override FrameworkElement 與 Control,建立自定義的控件還有別的方式,使用 XAML 比使用代碼的方式更常見,就是通過定義一個模板來達到此目的。
第235頁,第2自然段,第2句:
Panel 最大的好處是,它有 Children Property 可以進行孩子的排序。
英文原文是:
The big gift of Panel is the definition of Children property for storing the children.
我認為應(yīng)該這樣翻譯:
Panel 最大的好處是,它有一個用來存儲孩子們的 Children 屬性。
第239頁,第5自然段之后,漏了以下一個自然段:
In other words, the grid is behaving as we might hope and expect. To further test it, dig out the ColorGrid control from the last chapter and replace UniformGrid with UniformGridAlmost.
換句話說,grid 的行為可能符合我們的期望和預(yù)期。為了進一步測試它,找出上一章的 ColorGrid 控件,并且將其中的所有 UniformGrid 都替換為 UniformGridAlmost。
第451頁,NotePadClone.Help.cs 程序,中間位置:
? itemHelp.SubmenuOpened += ViewOnOpen;
這條語句應(yīng)該刪除(英文原版中就錯了)。
第466頁,第1句:
構(gòu)造函數(shù)為此 XML 資源建立一個 Uri 對象,然后使用靜態(tài)的 Application.GetResourceStream property,取得一個 StreamResourceInfo 對象。
這句話是英文原文的錯誤,不是譯者的翻譯錯誤。這句話應(yīng)該是這樣的:
構(gòu)造函數(shù)為此 XML 資源建立一個 Uri 對象,然后調(diào)用靜態(tài)的 Application.GetResourceStream 方法,取得一個 StreamResourceInfo 對象。
第468頁,第1自然段,第2句:
你可以使用此程序,加載本章至今的任何 XAML 文件(擴展名是 .xml)。
英文原文是:
You can use this program to load any of the XAML files shown is this chapter so far, including those with a file name extension of .xml.
我認為應(yīng)該這樣翻譯:
你可以使用此程序,加載本章至今的任何 XAML 文件,包括那些擴展名是 .xml 的文件。(譯者注:XAML 文件默認的擴展名是 .xaml)
第490頁,XamlCruncher.cs 程序,中間位置:
????? split = new GridSplitter();
????? split.HorizontalAlignment = HorizontalAlignment.Center;
????? split.VerticalAlignment = VerticalAlignment.Stretch;
????? split.Height = 6;
????? grid.Children.Add(split);
????? Grid.SetRow(split, 0);
????? Grid.SetColumn(split, 1);
????? Grid.SetRowSpan(split, 3);
應(yīng)改為(英文原版中就錯了,但該書網(wǎng)站上提供下載的源程序代碼是正確的):
????? split = new GridSplitter();
????? split.HorizontalAlignment = HorizontalAlignment.Center;
????? split.VerticalAlignment = VerticalAlignment.Stretch;
????? split.Width = 6;
????? grid.Children.Add(split);
????? Grid.SetRow(split, 0);
????? Grid.SetColumn(split, 1);
????? Grid.SetRowSpan(split, 3);
第512頁,最后1自然段(除了程序代碼以外):
然而,GradientStops property 必須變成一個 property element:
英文原文是:
The GradientStops property is of type GradientStopCollection, so we can put in an object element for that class:
我認為應(yīng)該這樣翻譯:
GradientSopts property 的類型是 GradientStopCollection,于是我們可以將其放到一個 object element 中:
第525頁,程序代碼之后的第1自然段:
注意 StackPanel element tag 定義了一個 XML 命名空間的前綴 s,代表 System 命名空間(clr-namespace:System;assembly=mscorlib),這允許引用此 Resources collection 中的 Double 結(jié)構(gòu)。
英文原文是:
Notice that the StackPanel element tag defines an XML namespace prefix of s for the System namespace (clr-namespace:System;assembly=mscorlib), which allows referencing the Double structure in the Resources collection.
我認為應(yīng)該這樣翻譯:
注意 StackPanel element tag 定義了一個 XML 命名空間的前綴 s,代表 System 命名空間(clr-namespace:System;assembly=mscorlib),這允許在此 Resources collection 中引用 Double 結(jié)構(gòu)。
第569頁,程序代碼之后的第1自然段,第2句:
然而,Page2 類沒有這一關(guān)鍵的 Navigate 方法,可以用于直接訪問 NavigationWindow 對象。
英文原文是:
However, the Page2 class doesn't have direct access to the NavigationWindow object with that crucial Navigate method.
我認為應(yīng)該這樣翻譯:
然而,Page2 類無法直接訪問 NavigationWindow 對象,該對象具有關(guān)鍵的 Navigate 方法。
第571頁,最后1自然段,第2句:
但是這里還有一個有趣的實驗:在 FrameNavigationDemoWindow.xaml 中,將 Window 改成 NavigationWindow,然后重新編譯。
這句話有問題,建議改為:
但是這里還有一個有趣的實驗:在 FrameNavigationDemoWindow.xaml 中,將 Window 改成 NavigationWindow,并添加一個 NavigationWindow.Content property element,然后重新編譯。
第584頁底部到第585頁頂部,DirectoryPage.xaml 源代碼:
DirectoryPage.xaml <!-- ================================================
????? DirectoryPage.xaml (c) 2006 by Charles Petzold
???? ================================================ -->
<PageFunction xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
????????????? xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
????????????? xmlns:io="clr-namespace:System.IO;assembly=mscorlib"
????????????? xmlns:tree="clr-namespace:Petzold.RecurseDirectoriesIncrementally"
????????????? x:Class="Petzold.ComputerDatingWizard.DirectoryPage"
????????????? x:TypeArguments="io:DirectoryInfo">
? <Grid>
??? <Grid.RowDefinitions>
????? <RowDefinition Height="Auto" />
????? <RowDefinition Height="*" />
????? <RowDefinition Height="Auto" />
??? </Grid.RowDefinitions>
??? <TextBlock Grid.Row="0" FontSize="16" FontStyle="Italic"
?????????????? HorizontalAlignment="Center">
????? Computer Dating Wizard
??? </TextBlock>
??? <tree:DirectoryTreeView x:Name="treevue" Grid.Row="1" />
??? <!-- Buttons at bottom-right corner of page. -->
??? <Grid Grid.Row="2">
????? <Grid.ColumnDefinitions>
??????? <ColumnDefinition Width="*" />
??????? <ColumnDefinition Width="Auto" />
??????? <ColumnDefinition Width="Auto" />
????? </Grid.ColumnDefinitions>
????? <Button Grid.Column="1" Click="CancelButtonOnClick"
????????????? IsCancel="True" MinWidth="60" Margin="6">
??????? Cancel
????? </Button>
????? <Button Grid.Column="2" Name="btnOk" Click="OkButtonOnClick"
????????????? IsEnabled="False" IsDefault="True" MinWidth="60" Margin="6">
??????? OK
????? </Button>
??? </Grid>
? </Grid>
</PageFunction>
應(yīng)改為:
DirectoryPage.xaml <!-- ================================================
????? DirectoryPage.xaml (c) 2006 by Charles Petzold
???? ================================================ -->
<PageFunction xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
????????????? xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
????????????? xmlns:io="clr-namespace:System.IO;assembly=mscorlib"
????????????? xmlns:tree="clr-namespace:Petzold.RecurseDirectoriesIncrementally"
????????????? x:Class="Petzold.ComputerDatingWizard.DirectoryPage"
????????????? x:TypeArguments="io:DirectoryInfo">
? <Grid>
??? <Grid.RowDefinitions>
????? <RowDefinition Height="*" />
????? <RowDefinition Height="Auto" />
??? </Grid.RowDefinitions>
??? <tree:DirectoryTreeView x:Name="treevue" Grid.Row="0" />
??? <!-- Buttons at bottom-right corner of page. -->
??? <Grid Grid.Row="1">
????? <Grid.ColumnDefinitions>
??????? <ColumnDefinition Width="*" />
??????? <ColumnDefinition Width="Auto" />
??????? <ColumnDefinition Width="Auto" />
????? </Grid.ColumnDefinitions>
????? <Button Grid.Column="1" Click="CancelButtonOnClick"
????????????? IsCancel="True" MinWidth="60" Margin="6">
??????? Cancel
????? </Button>
????? <Button Grid.Column="2" Name="btnOk" Click="OkButtonOnClick"
????????????? IsEnabled="False" IsDefault="True" MinWidth="60" Margin="6">
??????? OK
????? </Button>
??? </Grid>
? </Grid>
</PageFunction>
下面是修改前后程序運行的屏幕截圖:
?
第585頁,程序代碼之后的第1自然段,倒數(shù)第2句:
另一個命名空間的聲明關(guān)聯(lián)起“tree”前綴和第16章 RecurseDirectoriesIncrementally 工程的命名空間。
這句話后面漏了一句:
That's where the DirectoryTreeView class comes from that forms the bulk of this page.
我認為應(yīng)該這樣翻譯:
另一個命名空間的聲明關(guān)聯(lián)起“tree”前綴和第16章 RecurseDirectoriesIncrementally 工程的命名空間。而 RecurseDirectoriesIncrementally 命名空間正是此頁面主體部分的 DirectoryTreeView 類所在的命名空間。
第586頁,程序代碼之后的第1自然段,第1句:
構(gòu)造函數(shù)為 DirectoryTree 控件設(shè)置 ViewSelectionChanged 事件處理函數(shù),好讓 OK 按鈕“只有在磁盤驅(qū)動器目錄被選取的情況下”才會被 enable。
英文原文是(這句話中的“SelectionChanged”應(yīng)該是“SelectedItemChanged”):
The constructor attaches a SelectionChanged event handler to the DirectoryTreeView control so that the OK button is enabled only if a disk directory has been selected.
這認為應(yīng)該這樣翻譯:
構(gòu)造函數(shù)為 DirectoryTreeView 控件設(shè)置 SelectedItemChanged 事件處理函數(shù),好讓 OK 按鈕“只有在磁盤驅(qū)動器目錄被選取的情況下”才會被 enable。
第594頁,程序代碼之后的第1自然段,第1句:
這兩個 Hyperlink element 包含的不只是 NaviagateUri attribute (引用兩個 XML 文件),也包含了 TargetName attribute (引用 BookList.xaml 頁面上方的 Frame)。
英文原文是(這句話中的“BookList.xaml”應(yīng)該是“BookReader.xaml”):
The two Hyperlink elements contain not only NavigateUri attributes that reference two XAML files, but also TargetName attributes that reference the Frame at the left of the BookList.xaml page.
我認為應(yīng)該這樣翻譯:
這兩個 Hyperlink element 包含的不只是 NaviagateUri attribute (引用兩個 XML 文件),也包含了 TargetName attribute (引用 BookReader.xaml 頁面左邊的 Frame)。
第600頁,第1句:
WindowOnLoaded 事件處理函數(shù)會用 Tile 對象和 Empty 對象來為 UniformGrid 初始化。
應(yīng)該改為(這句話英文原文就是錯的):
PageOnLoaded 事件處理函數(shù)會用 Tile 對象和 Empty 對象來為 UniformGrid 初始化。
第607頁,程序代碼之后的第1自然段最后2句:
大多數(shù)情況下 Label.Content tag 不是必須的,你可以試著移除它。但是在這里,確實是必要的。
經(jīng)實驗,在這里,Label.Content tag 也不是必須的。也就是說,我試著移除它,程序照正常工作。
第609頁,最后1自然段,第1句:
現(xiàn)在 ScrollBar 的目標是由 Label 源來控制。
英文原文是:
Now the ScrollBar target is governing the Label source.
我認為應(yīng)該這樣翻譯:
現(xiàn)在 ScrollBar 目標控制 Label 源。
第612頁,除了程序代碼這外的第3個自然段(在該頁正中間):
這段 XAML 在我看起來好像沒問題,但卻拋出一個異常,告訴我“類型為‘System.Windows.Data.Binding’的對象無法轉(zhuǎn)換成‘System.String’”,這里顯然指的是 Text property 的類型。此消息對我來說非常奇怪,因為它言下之意是解析器正在忽略這個再自然不過的數(shù)據(jù)綁定定義。
在我的計算機上,拋出的異常是:不能在類型“Run”的“Text”屬性上設(shè)置“Binding”。只能在 DependencyObject 的 DependencyProperty 上設(shè)置“Binding”。
這個異常消息再正常不過了。我想本書作者看到的奇怪的異常消息可能是他使用 CTP 版本的 WPF 軟件的緣故。
第615頁,程序代碼之后的第2個自然段,第1句:
第一個 ScrollBar 定義一個 OneWayToSource 綁定,其 Number property 是第一個 SimpleElement。
英文原文是:
The first ScrollBar defines a OneWayToSource binding with the Number property of the first SimpleElement.
我認為應(yīng)該這樣翻譯:
第一個 ScrollBar 定義一個 OneWayToSource 綁定,綁定到第一個 SimpleElement 的 Number property。
第615頁,程序代碼之后的第3個自然段,第1句和第2句:
第二個 ScrollBar 定義一個 TwoWay 綁定,其 Number property 是第一個 SimpleElement,且你將會看到這個也順利工作。雖然 SimpleElement 沒有顯式的通知機制 ScrollBar,操作第一個 ScrollBar 產(chǎn)生的 Number property 的改變,會被此綁定檢測到,結(jié)果第二個會跟隨第一個 ScrollBar 變化。
英文原文是:
The second ScrollBar defines a TwoWay binding with the Number property of the first SimpleElement, and you'll see that this one works as well. Although SimpleElement has no explicit notification mechanism, changes to the Number property as a result of manipulating the first ScrollBar are detected in this binding, and the second ScrollBar tracks the first ScrollBar.
我認為應(yīng)該這樣翻譯:
第二個 ScrollBar 定義一個 TwoWay 綁定,綁定到第一個 SimpleElement 的 Number property,且你將會看到這個也順利工作。雖然 SimpleElement 沒有顯式的通知機制,操作第一個 ScrollBar 產(chǎn)生的 Number property 的改變,會被此綁定檢測到,結(jié)果第二個 ScrollBar 會跟隨第一個 ScrollBar 變化。
第615頁,程序代碼之后的第4個自然段,第1句:
第二個 SimpleElement element 定義了一個 OneWay 數(shù)據(jù)綁定。
英文原文是:
The second SimpleElement element defines a OneWay data binding with the second ScrollBar.
我認為應(yīng)該這樣翻譯:
第二個 SimpleElement element 定義了一個 OneWay 數(shù)據(jù)綁定,綁定到第二個 ScrollBar。
第627頁,倒數(shù)第2自然段,最后2句:
然而,有可能你真正需要的是“被此字段 property 所引用的對象”的某個 property。這種情況下,你需要使用綁定。
英文原文是:
However, it's possible that what you really need is a property of the object referenced by the static property. In that case, you need a binding.
我認為應(yīng)該這樣翻譯:
然而,有可能你真正需要的是“被此靜態(tài) property 所引用的對象”的某個 property。這種情況下,你需要使用綁定。
第631頁,從第2自然段開始,到“就這樣”。
原書上這一大段是論述如何定義一個名為 DateTimeChanged 的 public 事件,使用 WPF 數(shù)據(jù)綁定邏輯去更新 DateTime property。但是經(jīng)我實驗,這沒有效果。
第639頁,第4自然段,第1句和2句:
Style 類型定義在 System.Windows 中。其派生自 Object,且沒有子類。
應(yīng)改為(英文原文就是錯的):
Style 類型定義在 System.Windows 中。其派生自 DispatcherObject,且沒有子類。
第646頁,程序代碼之后的第2自然段:
如果你的應(yīng)用中有許多對話框,而這些對話框的 Stack Panel 包含一些 radio buttons (放在 Group box 內(nèi)),為了讓這些 Radio Button 看起來更美觀。RadioButton 的 TargetType 是很好的 Style 范例。
英文原文是:
If you have a bunch of dialog boxes in an application, and these dialog boxes have some radio buttons on stack panels within group boxes, you know you need to apply a Margin property to each RadioButton to make it look reasonably attractive. This is an excellent application of a Style with a TargetType of RadioButton.
我認為應(yīng)該這樣翻譯:
如果你的應(yīng)用中有許多對話框,而這些對話框的 Stack Panel 包含一些 radio buttons (放在 Group box 內(nèi)),為了讓這些 Radio Button 看起來更美觀,你知道需要為每個 Radio Button 應(yīng)用 Margin property。RadioButton 的 TargetType 是很好的 Style 范例。
第652頁,除了程序代碼之外的倒數(shù)第3自然段,第1句:
答案是 Binding 搭配 RelativeSource,這在本章最后會討論到。
英文原文是:
The solution is a Binding using RelativeSource, which I discussed toward the end of the previous chapter.
我認為應(yīng)該這樣翻譯:
答案是 Binding 搭配 RelativeSource,這已經(jīng)在上一章最后討論過。
第656頁,程序代碼之后的第1自然中間:
當 Seal 方法被調(diào)用時,只讀的 IsSeal property 被設(shè)定為 true。
英文原文是:
The read-only IsSealed property becomes true when the Seal method is called, which happpens when the style is in use.
我認為應(yīng)該這樣翻譯:
當 Sytle 被使用時,其 Seal 方法被調(diào)用,只讀的 IsSealed property 被設(shè)定為 true。
第677頁,程序代碼之后的第3自然段,最后1句:
TextBox 與 RichTextBox 控件具有相對簡單的模板,因為這兩個控件其實是 Border element,而 Border 包含 ScrollViewer 控件,ScrollViewer 再包含實際的編輯器,而編輯器則完全使用代碼實現(xiàn)。
這句話英文原文就是這樣,但在我的計算機上通過 DumpControlTemplate 程序卻得到以下結(jié)論:
TextBox 與 RichTextBox 控件具有相對簡單的模板,因為這兩個控件其實是 ListBoxChrome element,而 ListBoxChrome 包含 ScrollViewer 控件,ScrollViewer 再包含實際的編輯器,而編輯器則完全使用代碼實現(xiàn)。
第679頁,除了代碼之外的倒數(shù)第2自然段,第2句:
ContentPresenter 定義了 ContentTemplate property (對象為 DataTemplate),為的是要定義一個“用來顯示內(nèi)容”的模板。
ContentPresenter defines a property named ContentTemplate of type DataTemplate for defining a template used to display content.
我認為應(yīng)該這樣翻譯:
ContentPresenter 定義了 ContentTemplate property (類型為 DataTemplate),為的是要定義一個“用來顯示內(nèi)容”的模板。
第680頁,程序代碼之后的第2自然段,最后1句:
此 UniformGrid 包含一個 TextBlock (用來顯示雇員的名稱)和一個 StackPanel (具有兩個 TextBlock element,用來顯示雇員的生日)。
The UniformGrid has a TextBlock for the employee's name and then a StackPanel with six TextBlock elements that effectively format the employee's birth date.
我認為應(yīng)該這樣翻譯(英文原文誤為“six”):
此 UniformGrid 包含一個 TextBlock (用來顯示雇員的名稱)和一個 StackPanel (具有五個 TextBlock element,用來顯示雇員的生日)。
第694頁,第2自然段,第1句:
下面的 Resource section,先定義控件的 layout。
英文原文是:
Following the Resources section, the definition of the layout of the control begins.
我認為應(yīng)該這樣翻譯:
在 Resources section 之后,先定義控件的 layout。
第699頁,DatePicker.cs 程序代碼,最后一段:
??? // Buttons are duplicated by PageDown and PageUp keys.
??? protected override void OnPreviewKeyDown(KeyEventArgs args)
??? {
????? base.OnKeyDown(args);
????? if (args.Key == Key.PageDown)
????? {
??????? FlipPage(true);
??????? args.Handled = true;
????? }
????? else if (args.Key == Key.PageUp)
????? {
??????? FlipPage(false);
??????? args.Handled = false;
????? }
??? }
應(yīng)改為(英文原版就是錯的):
??? // Buttons are duplicated by PageDown and PageUp keys.
??? protected override void OnPreviewKeyDown(KeyEventArgs args)
??? {
????? base.OnPreviewKeyDown(args);
????? if (args.Key == Key.PageDown)
????? {
??????? FlipPage(true);
??????? args.Handled = true;
????? }
????? else if (args.Key == Key.PageUp)
????? {
??????? FlipPage(false);
??????? args.Handled = true;
????? }
??? }
第705頁,除了程序代碼之外的第4自然段:
XPath property 是一個 XML Path Language 字符串。關(guān)于 XML Path Language,你可以在 www.w3.org/TR/xpath 看到它的文件。
英文原文是:
The XPath property is a string defined in XML Path Language as documented at www.w3.org/TR/xpath, except that no functions are allowed.
我認為應(yīng)該這樣翻譯:
XPath property 是一個 XML Path Language 字符串(除了不支持 XPath 函數(shù))。關(guān)于 XML Path Language,你可以在 www.w3.org/TR/xpath 看到它的文檔。
第738頁,程序代碼中部(NavigationBar.cs),應(yīng)改為(其中紅色的一對大括號是新增的。英文原版就錯了):
??? void TextBoxOnLostFocus(object sender, KeyboardFocusChangedEventArgs args)
??? {
????? int current;
????? if (Int32.TryParse(txtboxCurrent.Text, out current))
????? {
??????? if (current > 0 && current <= coll.Count)
????????? collview.MoveCurrentToPosition(current - 1);
????? }
????? else
??????? txtboxCurrent.Text = strOriginal;
??? }
總結(jié)
- 上一篇: 网络游戏,原罪和救赎
- 下一篇: SVCHOST.exe进程之谜