程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> WPF Bug清單之(7)——頑固的Error Template

WPF Bug清單之(7)——頑固的Error Template

編輯:關於.NET

關於WPF數據綁定是什麼,請參考Data Binding Overview:http://msdn.microsoft.com/en-us/library/ms752347.aspx

關於WPF數據綁定的Validation更多細節,請參考Data Validation in 3.5:http://blogs.msdn.com/wpfsdk/archive/2007/10/02/data-validation-in-3-5.aspx

關於WPF數據綁定的Validation中的ErrorTemplate怎麼用,請參考ErrorTemplate Attached Property:http://msdn.microsoft.com/en-us/library/system.windows.controls.validation.errortemplate.aspx

ErrorTemplate將被繪制在Adorner Layer上,關於Adorner Layer,請參考Adorners Overview:http://msdn.microsoft.com/en-us/library/ms743737.aspx

在Adorners Overview裡,對Adorner是這樣解釋的,

Adorners are rendered in an AdornerLayer, which is a rendering surface that is always on top of the adorned element or a collection of adorned elements.

Adorned element的紅色是我加的。表面上看,這個adorned element就是一個element,但是這個element的范圍有多大呢?對我們的程序會有什麼影響呢?看文檔很難想到。用過之後才知道,影響太大了。

還有這樣一個不太起眼的Note。

Anything placed in the adorner layer is rendered on top of the rest of any styles you have set. In other words, adorners are always visually on top and cannot be overridden using z-order.

這句話是對的。大意就是說這個Adorner layer裡的東西,總會被繪制在它所adorn的東西之上。這個無可厚非,人家這樣設計,我們就這麼用就是了。但是,問題就在於,一個Window裡的東西,是可以有層次的,有區域,有可見性的。但是adorner layer不分青紅皂白地總在最上。結果就出了問題。請看下面的例子。

DemoWindow

<Window x:Class="FixErrorTemplate.DemoWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Stubborn Error Template Demo"
Height="200" Width="300"
ResizeMode="NoResize"
WindowStartupLocation="CenterScreen"
Name="window">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition Height="5"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid Height="50">
<TextBox HorizontalAlignment="Center" VerticalAlignment="Center" Width="100">
<TextBox.Text>
<Binding ValidatesOnDataErrors="True" ElementName="window" Path="Value"/>
</TextBox.Text>
</TextBox>
</Grid>
<GridSplitter Grid.Row="1" HorizontalAlignment="Stretch"/>
<Grid Grid.Row="2" Margin="12">
<TabControl>
<TabItem Header="Tab1">
<TextBox HorizontalAlignment="Center" VerticalAlignment="Center" Width="100">
<TextBox.Text>
<Binding ValidatesOnDataErrors="True" ElementName="window" Path="Value"/>
</TextBox.Text>
</TextBox>
</TabItem>
<TabItem Header="Tab2"/>
</TabControl>
</Grid>
</Grid>
</Window>

這個窗口,就出了兩個問題。看圖。

啟動時如下圖所示。

圖1. Startup Window

窗體的上下由一個GridSplitter分割,可以上下拖動。

在TextBox中輸入一個字符。會產生一個Validation Error,並用默認的ErrorTemplate顯示出來。如圖2所示。

圖2. TextBox in Error

好了,我們慢慢地將GridSplitter向上拖。慢慢地,看到什麼了?TextBox消失了,可是那個紅框卻賴著不走了!如圖3所示。

圖3. Move GridSplitter Up

再來看看下面的紅框。把GridSplitter慢慢地向下拖。TabPanel的空間小了,TextBox也變矮,最後消失,那個紅框也很盡忠,化成了一條線也要告訴我們那個TextBox其實還在。如圖4所示。

圖4. Move GridSplitter Down

再細看看,那個紅線甚至已經在TabControl之外了!

當然,我們總可以想辦法解決或是繞過這個問題,然後說這不是個問題。但是最自然的代碼寫出來的東西卻不對,就象之前一篇介紹的如何用代碼選中一個ListBoxItem一樣,很不爽。因為按理說,adorned element都消失了,這個紅框也應該跟著消失的。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved