如果您正在使用MVVM,那麼您的確定按鈕單擊必須由一些Command
來處理。該命令必須來自您的ViewModel
。綁定屬性Expliticly
必須來自ViewModel
。所以什麼阻止你。
- 請勿使用
Explicit
綁定,而是使用OneWay
綁定。
- 在您按鈕中,綁定命令並將命令參數綁定到綁定的依賴項屬性的
OneWay
。
- 在您的Command的Execute處理程序(必須是ViewModel中的某個方法)中,使用參數來更改ViewModel的屬性。
- 從
ViewModel
提高該房產的NotifyPropertyChanged
。
例如,
假設我需要將一個TextBox的文本更新到我的模型上,單擊OK按鈕。
因此,我有一個EmployeeViewModel
類具有EmployeeName
屬性。該物業有一個吸氣和一個二傳手。 setter引發屬性更改通知。視圖模型還有ICommand
的另一個屬性,名爲SaveNameCommand
,它返回一個命令讓我執行。
EmployeeViewModel
是我的視圖的數據上下文類型。 Myview有一個TextBox
(命名爲x:Name =「EmployeeNameTxBx」)OneWay
綁定到EmployeeName
和一個按鈕作爲OK
。我將Button.Command
屬性綁定到EmployeeViewModel.SaveNameCommand
屬性,並將Button.CommandParameter
綁定到EmployeeNameTxBx.Text
屬性。
<StackPanel>
<TextBox x:Name="EmployeeNameTxBx"
Text="{Binding EmployeeName, Mode=OneWay}" />
<Button Content="OK"
Command="{Binding SaveNameCommand}"
CommandParameter="{Bidning Text, ElementName=EmployeeNameTxBx}" />
</StackPanel>
裏面我EmployeeViewModel
我OnSaveNameCommandExecute(object param)
方法來執行我的SaveNameCommand
。
在此執行這個代碼...
var text = (string)param;
this.EmployeeName = text;
這樣,只有OK按鈕點擊,更新文本框的文本回復到模型的EmployeeName
財產。
編輯
看着下面您的意見,我看你是想實現一個UI驗證。現在這改變了一點點。
IDataErrorInfo
和相關驗證只適用於如果您的輸入控件(如文本框)爲雙向約束。是的,它是如何打算的。所以現在你可能會問:「如果我們使用IDataErrorInfo,這是否意味着不允許無效數據傳遞給模型的整個概念在MVVM中是徒勞的?」其實不是!
請參閱MVVM不強制執行一條規則,即只有有效的數據應該返回。它接受無效數據,這就是IDataErrorInfo
的工作原理,並提出錯誤通知。關鍵是ViewModel只是你的視圖的軟拷貝所以它可以是髒。它應該確保這種骯髒不是承諾到您的外部接口,如服務或數據庫。
這樣的無效數據流應該通過測試無效數據來限制ViewModel
。如果我們啓用了TwoWay
綁定,那麼數據就會出現。所以考慮到你正在實現IDataErrorInfo
,那麼你需要有TwoWay
綁定,這是MVVM完全允許的。
方法1:
如果我婉明確確認上按鈕UI某些項目點擊?
爲此使用延遲驗證技巧。在你的ViewModel中有一個叫做isValidating的標誌。默認設置爲false。
在你IDataErrorInfo.this
財產通過檢查isValidating標誌跳過驗證...
string IDataErrorInfo.this[string columnName]
{
get
{
if (!isValidating) return string.Empty;
string result = string.Empty;
bool value = false;
if (columnName == "EmployeeName")
{
if (string.IsNullOrEmpty(AccountType))
{
result = "EmployeeName cannot be empty!";
value = true;
}
}
return result;
}
}
然後在執行處理您的OK命令,檢查員工的名稱,然後提高屬性更改通知事件相同的屬性...
private void OnSaveNameCommandExecute(object param)
{
isValidating = true;
this.NotifyPropertyChanged("EmployeeName");
isValidating = false;
}
這會在您單擊確定時觸發驗證。請記住EmployeeName
必須包含用於驗證才能工作的無效數據。
方法2:
如果我想在MVVM明確地更新沒有雙向模式的綁定?
然後你將不得不使用Attached Behavior
。該行爲將附加到「確定」按鈕,並將接受需要刷新其綁定的所有項目的列表。
<Button Content="OK">
<local:SpecialBindingBehavior.DependentControls>
<MultiBinding Converter="{StaticResource ListMaker}">
<Binding ElementName="EmployeeNameTxBx" />
<Binding ElementName="EmployeeSalaryTxBx" />
....
<MultiBinding>
</local:SpecialBindingBehavior.DependentControls>
</Button>
的ListMaker
是IMultiValueConverter
簡單地轉換值成列表...
Convert(object[] values, ...)
{
return values.ToList();
}
在你SpecialBindingBehavior
有DependentControls
屬性更改處理器...
private static void OnDependentControlsChanged(
DependencyObject depObj,
DependencyPropertyChangedEventArgs e)
{
var button = sender as Button;
if (button != null && e.NewValue is IList)
{
button.Click
+= new RoutedEventHandler(
(object s, RoutedEventArgs args) =>
{
foreach(var element in (IList)e.NewValue)
{
var bndExp
= ((TextBox)element).GetBindingExpression(
((TextBox)element).Textproperty);
bndExp.UpdateSource();
}
});
}
}
但我還是建議你使用基於我以前純MVVM **方法1。
首先感謝您的詳細解答!並回到我的問題,我使用純mvvm,我有我的虛擬機命令,我使用NotifyPropertyChanged。但如果我使用OneWay綁定,並在窗口10文本框中它的意思是我需要發送命令參數10個元素名稱?然後手動更新它們?有沒有辦法使用ToWay綁定? – Maya
也現在我使用IDataError來驗證文本框中的文本,如果我將使用OneWay綁定,我仍然可以驗證文本? – Maya
@Maya請看我上面編輯過的naswer。 –