WPF資料繫結概觀(二)---使用ValueConverter
上一篇文章講到了一個簡單的控制項屬性繫結的做法,直接將繫結目標屬性的值直接傳給繫結目標的屬性並不一定很適用,例如上一篇文章中直接將ProgressBar的Value直接在TextBlock裡顯示,一般的做法上或許會另外在這個TextBlock的前後再加入其它的TextBlock,將整個顯示的結果變成TextBlock(目前進度)+(繫結來源的Value)+TextBlock(%),這樣的佈置同樣可以達到將單純的ProgressBar.Value以一串字串顯示的效果,但是別忘了,一般的進度顯示是以0~1的double值來顯示,因此我們常會碰到的ProgressBar的Maximum會是1,而Minimum則會是0,如果你是將取得的值轉換成百分比再丟入ProgressBar.Value,這當然就沒有顯示的問題!不過如果是以一連串的資料繫結來做,例如將ProgressBar.Value繫結至某個類別的下載進度,再將TextBlock.Text繫結至ProgressBar.Value,在這連續的繫結中我們勢必在這兩個繫結的過程裡進行資料的換算!
一個方式是在下載進度繫結至ProgressBar.Value時將進度值*100,另一個方式則是在TextBlock繫結至ProgressBar.Value時再進行換算,這兩種方式都可以,而在資料繫結的過程中要進行數值換算
System.Windows.Threading.DispatcherTimer _timer = new System.Windows.Threading.DispatcherTimer();
private void Button_Click(object sender, RoutedEventArgs e)
{
progressBar.Maximum = 1;
progressBar.Minimum = 0;
progressBar.Value = 0;
Binding pbBinding = new Binding();
pbBinding.Source = progressBar;
pbBinding.Path = new PropertyPath(ProgressBar.ValueProperty);
tbValue.SetBinding(TextBlock.TextProperty, pbBinding);
_timer.Interval = new TimeSpan(0, 0, 1);
_timer.Tick += new EventHandler(_timer_Tick);
_timer.Start();
}
void _timer_Tick(object sender, EventArgs e)
{
if (progressBar.Value < 1)
{
progressBar.Value += 0.01;
}
else
{
_timer.Stop();
}
}
我將原本的程式加入初始值並進行一些修改,讓它更符合實際的狀況,從上面的程式可以知道,每秒會讓ProgressBar.Value的值+0.01,這個時候TextBlock顯示的值必定是介於0~1,我們可以試著將這0~1的值轉換成百分比,首先我們先建立一個新的類別,我將這個類別命名為ValueConveryter:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Data;
namespace PropertyBinding
{
class ValueConverter:IValueConverter
{
#region IValueConverter 成員
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
string pbValueString = ((double)value*100).ToString();
return "目前進度" + pbValueString + "%";
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
#endregion
}
}
這個類別必須實作System.Windows.Data.IValueConverter介面,而IValueConverter 只有兩個成員,Converter與ConverterBack,Converter用於來源屬性值流向目標屬性值;而ConverterBack則是用於雙向繫結,也就是目標屬性值回傳至來源屬性值時的轉換,不過在這個例子裡我們只實作Converter成員,紅色字的部分就是我們新增的程式碼,很簡單的程式,我想不必再多說明什麼了吧?而使用ValueConverter時只要將Binding物件的Converter屬性指定為我們新建的ValueConverter類別即可,如下面紅字部分:
System.Windows.Threading.DispatcherTimer _timer = new System.Windows.Threading.DispatcherTimer();
private void Button_Click(object sender, RoutedEventArgs e)
{
progressBar.Maximum = 1;
progressBar.Minimum = 0;
progressBar.Value = 0;
Binding pbBinding = new Binding();
pbBinding.Source = progressBar;
pbBinding.Path = new PropertyPath(ProgressBar.ValueProperty);
pbBinding.Converter = new ValueConverter();
tbValue.SetBinding(TextBlock.TextProperty, pbBinding);
_timer.Interval = new TimeSpan(0, 0, 1);
_timer.Tick += new EventHandler(_timer_Tick);
_timer.Start();
}
void _timer_Tick(object sender, EventArgs e)
{
if (progressBar.Value < 1)
{
progressBar.Value += 0.01;
}
else
{
_timer.Stop();
}
}
如此一來我們就可以順利地將double值轉換為百分比,並以我們想要的字串輸出!