欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

WPF數(shù)據(jù)綁定時出現(xiàn)StringFormat失效的原因和解決方法

 更新時間:2024年12月10日 11:13:36   作者:小碼編匠  
在數(shù)據(jù)綁定過程中,我們經(jīng)常會使用StringFormat對要顯示的數(shù)據(jù)進行格式化,以便獲得更為直觀的展示效果,但在某些情況下格式化操作并未生效,所以本文介紹了WPF數(shù)據(jù)綁定時出現(xiàn)StringFormat失效的原因和解決方法,需要的朋友可以參考下

前言

在數(shù)據(jù)綁定過程中,我們經(jīng)常會使用StringFormat對要顯示的數(shù)據(jù)進行格式化,以便獲得更為直觀的展示效果,但在某些情況下格式化操作并未生效,例如 ButtonContent屬性以及ToolTip屬性綁定數(shù)據(jù)進行StringFormat時是無效的。

首先回顧一下StringFormat的基本用法。

StringFormat的用法

StringFormatBindingBase的屬性,指定如果綁定值顯示為字符串,應(yīng)如何設(shè)置該綁定的格式。

因此,BindingBase 的三個子類:BindingMultiBinding、PriorityBinding都可以對綁定數(shù)據(jù)進行格式化。

Binding

Binding 是最常用的綁定方式,使用StringFormat遵循.Net格式字符串標準即可。

例如:

<TextBlock Text="{Binding Price,ElementName=self,StringFormat={}{0:C}}"/>

或者

<TextBlock Text="{Binding TestString,ElementName=self,StringFormat=test:{0}}"/>

其中{0}表示第一個數(shù)值,如果 StringFormat 屬性的值是以花括號開頭,前邊需要有一對花括號 {} 進行轉(zhuǎn)義,也就是第一個例子中的 {}{0:C},否則不需要,如第二個示例一樣。

如果設(shè)置 ConverterStringFormat屬性,則首先將轉(zhuǎn)換器應(yīng)用于數(shù)據(jù)值,然后StringFormat 應(yīng)用該值。

MultiBinding

Binding 綁定時,格式化只能指定一個參數(shù),MultiBinding 綁定時則可指定多個參數(shù)。

例如:

<TextBlock>
    <TextBlock.Text>
        <MultiBinding StringFormat="{}{0} {1}">
            <Binding Path="FirstName" ElementName="self"/>
            <Binding Path="LastName" ElementName="self"/>
        </MultiBinding>
    </TextBlock.Text>
</TextBlock>

這個例子中 MultiBinding 是由多個子 Binding 組成,StringFormat 僅在設(shè)置 MultiBinding 時適用,子 Binding 中雖然也可以設(shè)置 StringFormat,但是會被忽略。

PriorityBinding

相比于前兩種綁定,PriorityBinding 使用的頻率沒那么高,它的主要作用是按照一定優(yōu)先級順序設(shè)置綁定列表, 如果最高優(yōu)先級綁定在處理時成功返回值,則無需處理列表中的其他綁定。

如果計算優(yōu)先級最高的綁定需要很長時間,那么將會使用成功返回值的次高優(yōu)先級,直到優(yōu)先級較高的綁定成功返回值。

PriorityBinding 和其包含的綁定列表中的子 Binding 也都可以設(shè)置 StringFormat 屬性。

例如:

<TextBlock
    Width="100"
    HorizontalAlignment="Center"
    Background="Honeydew">
    <TextBlock.Text>
        <PriorityBinding FallbackValue="defaultvalue" StringFormat="haha:{0}">
            <Binding IsAsync="True" Path="SlowestDP" StringFormat="hi:{0}"/>
            <Binding IsAsync="True" Path="SlowerDP" />
            <Binding Path="FastDP" />
        </PriorityBinding>
    </TextBlock.Text>
</TextBlock>

MultiBinding 不同的是,PriorityBinding 的子 Binding中的 StringFormat是會生效的,其規(guī)則是優(yōu)先使用子 Binding 設(shè)置的格式,其次才使用PriorityBinding 設(shè)置的格式。

Content屬性格式化失效的原因

ButtonContent 屬性可以用字符串賦值并顯示在按鈕上,但是使用 StringFormat 格式化并不會生效。

原本我以為是涉及到類型轉(zhuǎn)換器,在類型轉(zhuǎn)換過程中處理掉了,但這只是猜測,通過源碼發(fā)現(xiàn)并不是這樣的。

BindingExpressionBase 中有這樣一段代碼:

internal virtual bool AttachOverride(DependencyObject target, DependencyProperty dp)
{
	_targetElement = new WeakReference(target);
	_targetProperty = dp;
	DataBindEngine currentDataBindEngine = DataBindEngine.CurrentDataBindEngine;
	if (currentDataBindEngine == null || currentDataBindEngine.IsShutDown)
	{
		return false;
	}
	_engine = currentDataBindEngine;
	DetermineEffectiveStringFormat();
	DetermineEffectiveTargetNullValue();
	DetermineEffectiveUpdateBehavior();
	DetermineEffectiveValidatesOnNotifyDataErrors();
	if (dp == TextBox.TextProperty && IsReflective && !IsInBindingExpressionCollection && target is TextBoxBase textBoxBase)
	{
		textBoxBase.PreviewTextInput += OnPreviewTextInput;
	}
	if (TraceData.IsExtendedTraceEnabled(this, TraceDataLevel.Attach))
	{
		TraceData.TraceAndNotifyWithNoParameters(TraceEventType.Warning, TraceData.AttachExpression(TraceData.Identify(this), target.GetType().FullName, dp.Name, AvTrace.GetHashCodeHelper(target)), this);
	}
	return true;
}

其中第11行調(diào)用了一個名為 DetermineEffectiveStringFormat 的方法,顧名思義就是檢測有效的 StringFormat。接下來看看里邊的邏輯:

internal void DetermineEffectiveStringFormat()
{
	Type type = TargetProperty.PropertyType;
	if (type != typeof(string))
	{
		return;
	}
	string stringFormat = ParentBindingBase.StringFormat;
	for (BindingExpressionBase parentBindingExpressionBase = ParentBindingExpressionBase; parentBindingExpressionBase != null; parentBindingExpressionBase = parentBindingExpressionBase.ParentBindingExpressionBase)
	{
		if (parentBindingExpressionBase is MultiBindingExpression)
		{
			type = typeof(object);
			break;
		}
		if (stringFormat == null && parentBindingExpressionBase is PriorityBindingExpression)
		{
			stringFormat = parentBindingExpressionBase.ParentBindingBase.StringFormat;
		}
	}
	if (type == typeof(string) && !string.IsNullOrEmpty(stringFormat))
	{
		SetValue(Feature.EffectiveStringFormat, Helper.GetEffectiveStringFormat(stringFormat), null);
	}
}

這段代碼的作用就是檢測有效的 StringFormat,并通過 SetValue 方法保存起來,從第4~7行代碼可以看到,一開始就會檢測目標屬性的類型是不是 String 類型,不是的話直接返回,綁定表達式中的 StringFormat 也就不會保存了。

在后續(xù)的 BindingExpression 類計算綁定表達式值時獲取到 StringFormatnull,也就不會進行格式化了。

Button 的 Content 屬性雖然可以用字符串賦值,但它其實的 Object 類型。因此,在檢測有效的 StringFormat 表達式時直接過濾了。ToolTip也同樣是 Object 類型。

解決方法

對于 Content 這種 Object 類型的屬性綁定字符串并且需要格式化時,可以采用以下三種方式解決:

1、最通用的方法就是自定義 ValueConverter,在 ValueConverter 中對字符串進行格式化;

2、綁定到其他可進行 StringFormat 的屬性上,比如 TextBlockText 屬性進行格式化,ToolTip 綁定到 Text 上;

3、既然是 Object 類型,那也可把 TextBlock 作為 Content的值。

<Button Width="120" Height="30">
    <Button.Content>
        <TextBlock Text="{Binding TestString,ElementName=self,StringFormat=test:{0}}"/>
    </Button.Content>
</Button>

小結(jié)

數(shù)據(jù)綁定時出現(xiàn)StringFormat失效的主要分為兩種情況。一是沒有遵循綁定時StringFormat使用的約束,二是綁定的目標屬性不是 String 類型。

最后

以上就是WPF數(shù)據(jù)綁定時出現(xiàn)StringFormat失效的原因和解決方法的詳細內(nèi)容,更多關(guān)于WPF StringFormat失效的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Qt程序中調(diào)用C#編寫的dll(推薦)

    Qt程序中調(diào)用C#編寫的dll(推薦)

    這篇文章主要介紹了Qt程序中調(diào)用C#編寫的dll,本文圖文并茂給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-04-04
  • C#實現(xiàn)會移動的文字效果

    C#實現(xiàn)會移動的文字效果

    這篇文章主要為大家詳細介紹了C#實現(xiàn)會移動的文字效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-04-04
  • C#遞歸算法之分而治之策略

    C#遞歸算法之分而治之策略

    分而治之的策略主要是將大量復(fù)雜的問題分成多個子問題,解決各個子問題,從而解決原問題,下面就讓我們看看具體如何實現(xiàn)。
    2016-06-06
  • C#讀寫txt文件的2種方法

    C#讀寫txt文件的2種方法

    這篇文章主要為大家詳細介紹了C#讀寫txt文本文檔數(shù)據(jù)的2種方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • c#連接sqlserver數(shù)據(jù)庫、插入數(shù)據(jù)、從數(shù)據(jù)庫獲取時間示例

    c#連接sqlserver數(shù)據(jù)庫、插入數(shù)據(jù)、從數(shù)據(jù)庫獲取時間示例

    這篇文章主要介紹了c#連接sqlserver數(shù)據(jù)庫、插入數(shù)據(jù)、從數(shù)據(jù)庫獲取時間示例,需要的朋友可以參考下
    2014-05-05
  • WPF下如何自定義MessageBox消息提示

    WPF下如何自定義MessageBox消息提示

    這篇文章主要介紹了WPF下如何自定義MessageBox消息提示問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • C#?中的"智能枚舉"之如何在枚舉中增加行為(示例代碼)

    C#?中的"智能枚舉"之如何在枚舉中增加行為(示例代碼)

    這篇文章主要介紹了C#?中的“智能枚舉”之如何在枚舉中增加行為(示例代碼),智能枚舉跟設(shè)計模式的意義一樣,可以幫助您避免重復(fù)的代碼,并提高代碼的可讀性和可維護性,需要的朋友可以參考下
    2023-05-05
  • C# .NET 中的緩存實現(xiàn)詳情

    C# .NET 中的緩存實現(xiàn)詳情

    軟件開發(fā)中最常用的模式之一是 緩存 ,其包括進程內(nèi)緩存、持久性進程內(nèi)緩存和分布式緩存,本文我們將主要介紹進程內(nèi)緩存,需要的朋友可以參考下面文章的具體內(nèi)容
    2021-09-09
  • 關(guān)于C#泛型列表List<T>的基本用法總結(jié)

    關(guān)于C#泛型列表List<T>的基本用法總結(jié)

    本篇文章主要是對C#中泛型列表List<T>的基本用法進行了詳細的總結(jié)介紹,需要的朋友可以過來參考下,希望對大家有所幫助
    2014-01-01
  • 詳解Unity中Mask和RectMask2D組件的對比與測試

    詳解Unity中Mask和RectMask2D組件的對比與測試

    本篇文章給大家介紹Unity中Mask和RectMask2D組件的對比與測試,包括組件用法及RectMask2D的基本用法,通過Mask的原理分析實例代碼相結(jié)合給大家講解的非常詳細,需要的朋友參考下吧
    2021-06-06

最新評論