WPF Knowledge Points - Binding.StringFormat不起作用的原理和解決


引出問題

我們先用一個簡單的例子引出問題:有一個DateTime資源,分別用TextBox,Label顯示這個DateTime。

<Grid>
<Grid.Resources>
<sys:DateTime x:Key="DateTime001">03/29/2012 15:05:30</sys:DateTime>
</Grid.Resources>
<TextBox Text="{Binding Source={StaticResource DateTime001},StringFormat=dddd , Mode=OneWay}"
Height
="23" HorizontalAlignment="Left" Margin="28,68,0,0" Name="textBox1" VerticalAlignment="Top" Width="120" />
<Label Content="{Binding Source={StaticResource DateTime001}, StringFormat=dddd, Mode=OneWay}"
Height
="28" HorizontalAlignment="Left" Margin="28,26,0,0" Name="label1" VerticalAlignment="Top" Width="120" />
</Grid>

運行結果如圖:

TextBox按照預期的,顯示了完整的英文星期,但是Label的格式沒有任何改變。我們用了完全一樣的Binding和格式字符串,區別究竟在什么地方?如果夠細心的話可以發現,TextBox的Binding是在Text屬性上進行的,而Label的Binding是在Content屬性上進行的。

 

詳細分析

本質原因:Control.Content是Object類型,而Binding.StringFormat僅僅在Binding的Property類型為string的時候才有效。

通過下面Label的Binding流程(來源於Stackoverflow牛人),我們可以看到底層的細節:
1. Binding把DateTime類型的值裝箱,賦值給Label.Content.
2. Label的Template包含ContentPresenter,用來顯示內容。
3. Label的ContentPresenter會會依次尋找ContentTemplate,DataTemplate去顯示內容,當而這都沒有找到的時候,它會用默認的Template。
4. ContentPresenter使用的默認Template用Label.ContentStringFormat屬性去格式化object到string。
5. 注意,以上是簡化的流程,本質的,ContentPresenter會用自身的Template和StringFormat顯示結果,但是由於在Label控件裝載過程中,會自動把Label的ContentTemplate和ContentStringFormat對應綁定到ContentPresenter的ContentTemplate和StringFormat。ContentPresenter本質會優先用Label的ContentTemplate和ContentStringFormat顯示。所以,我們這里說CotentPresenter用Label的Properties做顯示也沒有問題。

所以,對於非String類型的Content來說,添加屬性定義ContentStringFormat=dddd就可以顯示我們需要的結果了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM