我有一個窗體上的WPF文本框,以允許輸入一個URI。使用WPF文本框與URI轉換器,無效輸入擦除文本框
我試圖用數據轉換器來做到這一點。問題是當文本框綁定更新和文本框不包含有效的URI時,
- 數據轉換器返回空;
- 它將我的模型屬性設置爲null;
- 這會導致屬性更改事件觸發;
- 該文本框值設置爲空字符串,擦了用戶輸入無效
我是一個新手WPF,我茫然地找到使用數據轉換器的簡單圖案不會導致這種行爲。我認爲必須有一個標準模式來使用,我知道我是否是一個有經驗的WPF程序員。看看棱鏡4中包含的例子,似乎有兩種不同的方法使用。我不喜歡他們兩個。
第一種方法是當我的模型屬性設置爲null時引發異常,並將其捕獲並顯示爲驗證錯誤。問題是我希望該屬性能夠設置爲空 - 每次打開表單時,這些字段都設置爲其先前的值。如果應用程序以前從未運行過,則URI將被設置爲空 - 這不會引發異常。另外,使用例外進行驗證非常困難。
第二種方法是當屬性設置爲null時,將模型的驗證狀態設置爲包含屬性無效但不實際更新屬性。我認爲這很糟糕。它導致模型內部不一致,聲稱DCSUri無效,但包含之前有效的DCSUri值。
我用來避免這些問題的方法是在我的ViewModel中有一個字符串DCSUri,它只更新我的模型的Uri類型DCSUri屬性(如果它是有效的URI)。但我更喜歡使用轉換器並將我的文本框直接綁定到我的模型的方法。
我的轉換代碼:
/// <summary>
/// Converter from Uri to a string and vice versa.
/// </summary>
public class StringToUriConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
Uri uri = null;
string stringValue = value as string;
if (stringValue != null)
Uri.TryCreate(stringValue, UriKind.Absolute, out uri);
return uri;
}
}
的XAML的文本框:
<TextBox Grid.Row="1" Grid.Column="1" Name="DCSUriTextBox"
Text="{Binding Path=DCSLoadSettings.DCSUri, Mode=TwoWay, UpdateSourceTrigger=LostFocus, ValidatesOnExceptions=True, NotifyOnValidationError=True, ValidatesOnDataErrors=True, Converter={StaticResource StringToUriConverter} }"
HorizontalAlignment="Stretch" Height="Auto" VerticalAlignment="Center" Margin="5,0,20,0" IsReadOnly="{Binding Path=IsNotReady}" Grid.ColumnSpan="2" />
而對於我的模型內的DCSUri屬性的代碼:
/// <summary>
/// The Uri of the DCS instance being provided configuration
/// </summary>
public Uri DCSUri
{
get
{
return mDCSUri;
}
set
{
if (!Equals(value, mDCSUri))
{
mDCSUri = value;
this["DCSUri"] = value == null
? "Must provide a Uri for the DCS instance being provided configuration"
: string.Empty;
RaisePropertyChanged(() => DCSUri);
}
}
}
感謝HB ......我必須承認,我發現微軟的例子惱人的狀態有時候,因爲我一直使用的實踐來自於Prism包含的參考實現。他們對ValidationRules等沒有提及,並鼓勵您實現IDataErrorInfo或INotifyDataErrorInfo。有沒有IDataErrorInfo/INotifyDataErrorInfo的地方,還是應該使用ValidationRules完成驗證? – SamStephens 2011-04-26 01:00:38
我無法回答,因爲我對這些接口沒有經驗,對不起。從查看MSDN引用看,它看起來像IDataErrorInfo是古老的,而ValiationRule只有參考版本回到.NET 3.0,所以我懷疑ValidationRules是首選,特別是因爲它被集成到綁定引擎中。 – 2011-04-26 01:10:57
http://stackoverflow.com/questions/2980853/idataerrorinfo-vs-validationrule-vs-exception/2982656#2982656有一個很好的解釋。基本上,在模型中使用IDataErrorInfo來處理錯誤,在視圖中使用ValidationRule來處理錯誤。就我而言,無效的Uri在視圖中是錯誤的,所以您給我的ValidationRule實現是合適的。謝謝您的幫助! – SamStephens 2011-04-26 21:16:37