2014-01-22 92 views
3

案件是:我有一個控件的事件,我希望我的ViewModel作出反應。目前我通過執行隱藏按鈕的命令來執行此操作,如下例所示。將事件傳遞給ViewModel的最佳方式是什麼?

在View.xaml:

<Control x:Name="SearchResultGrid" ... DataRefreshed="SearchResultRefreshed" /> 
<Button x:Name="SearchResultRefreshedButton" Visibility="Collapsed" Command="{Binding SearchResultRefreshedCommand}" /> 

在View.xaml.cs:

private void SearchResultRefreshed(object sender, EventArgs e) 
{ 
    if (SearchResultRefreshedButton.Command != null) 
    { 
     SearchResultRefreshedButton.Command.Execute(SearchResultGrid.ResultRowCount); 
    } 
} 

這工作不錯,但它看起來像一個黑客給我。我想知道是否有更好的(標準)方法來做到這一點?我找不到任何例子,這就是我自己「發明」的。

+0

Google用於交互觸發器。 –

+0

或者只是將視圖的DataContext轉換爲ViewModel並做任何您想要做的事情.ViewModel vm = this.DataContext as ViewModel;那麼你可以做vm。SomeAction – Krishna

+0

@RohitVats謝謝,我看到在一些例子中使用它們,但它看起來並不像我所需要的。現在我發現我錯了。 – Kurtevich

回答

7

使用MVVM,處理事件的一般方法是簡單地將它們包裝在Attached Properties中,或使用Attached Events。這裏是附加屬性使用PreviewKeyDown事件爲例:

public static DependencyProperty PreviewKeyDownProperty = DependencyProperty.RegisterAttached("PreviewKeyDown", typeof(KeyEventHandler), typeof(TextBoxProperties), new UIPropertyMetadata(null, OnPreviewKeyDownChanged)); 

public static KeyEventHandler GetPreviewKeyDown(DependencyObject dependencyObject) 
{ 
    return (KeyEventHandler)dependencyObject.GetValue(PreviewKeyDownProperty); 
} 

public static void SetPreviewKeyDown(DependencyObject dependencyObject, KeyEventHandler value) 
{ 
    dependencyObject.SetValue(PreviewKeyDownProperty, value); 
} 

public static void OnPreviewKeyDownChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e) 
{ 
    TextBox textBox = dependencyObject as TextBox; 
    if (e.OldValue == null && e.NewValue != null) textBox.PreviewKeyDown += TextBox_PreviewKeyDown; 
    else if (e.OldValue != null && e.NewValue == null) textBox.PreviewKeyDown -= TextBox_PreviewKeyDown; 
} 

private static void TextBox_PreviewKeyDown(object sender, KeyEventArgs e) 
{ 
    TextBox textBox = sender as TextBox; 
    KeyEventHandler eventHandler = GetPreviewKeyDown(textBox); 
    if (eventHandler != null) eventHandler(sender, e); 
} 

注意,它也很容易(和更好的太)使用的ICommand而不是實際的KeyEventArgs對象不應該真正在的查看模型。只要創建ICommand類型的附加屬性和調用,從這個TextBox_PreviewKeyDown處理程序來代替:

private static void TextBox_PreviewKeyDown(object sender, KeyEventArgs e) 
{ 
    TextBox textBox = sender as TextBox; 
    ICommand command = PreviewKeyDownCommand(textBox); 
    if (command != null && command.CanExecute(textBox)) command.Execute(textBox); 
} 

無論哪種方式,它會使用這樣的:

<TextBox TextBoxProperties.PreviewKeyDown="SomeKeyEventHandler" /> 

或者,如果你使用的首選ICommand方法:

<TextBox TextBoxProperties.PreviewKeyDownCommand="{Binding SomeCommand}" /> 
+0

這看起來很有趣...我需要檢查它是如何工作的。 – Kurtevich

+0

這工作,我也很喜歡這個解決方案如何清潔,簡單,簡單就是。我也被告知過交互性觸發器,但我認爲這樣更好。謝謝! – Kurtevich

+0

你可以顯示附加事件的方式嗎?我無法找到如何在虛擬機上使用附加事件註冊事件處理程序,因爲所有路由事件都不支持綁定,或者不是嗎? –

0

您應該向您的控件添加依賴項屬性DataRefreshed以綁定它

這裏一個例子你如何能做到這一點

public static readonly DependencyProperty DataRefreshedProperty = DependencyProperty.Register(
    "DataRefreshed", 
    typeof(bool), 
    typeof("typeof yourcontrol here "), 
    new FrameworkPropertyMetadata(null, 
     FrameworkPropertyMetadataOptions.AffectsRender, 
     new PropertyChangedCallback(OnDataRefreshedChanged) 
) 
); 
public bool DataRefreshed 
{ 
    get { return (bool)GetValue(DataRefreshedProperty); } 
    set { SetValue(DataRefreshedProperty, value); } 
} 

然後你可以操縱你的財產像任何其他WPF財產中您的視圖模型中定義

<Control x:Name="SearchResultGrid" ... DataRefreshed="{Binding SearchResultRefreshed}" /> 
<Button x:Name="SearchResultRefreshedButton" Visibility="Collapsed" Command="{Binding SearchResultRefreshedCommand}" /> 

看一看例如SearchResultRefreshed在下面的教程瞭解更多dependecyproperty and attachedproperty

2

我個人從來沒有需要使用附加屬性來處理wi控制的事件。在你的例子中,一個控件想知道什麼時候'SearchResultRefreshed',然後通過隱藏的控件通知ViewModel ...爲什麼ViewModel不知道結果已經刷新?

如果結果首先來自ViewModel,並且綁定用於在控件中顯示它們,那麼搜索結果已刷新的知識應該由您的ViewModel驅動 - 而不是您的視圖。

在只有少數情況下,我發現需要擺脫ICommands和數據綁定。

+0

是,該數據被從視圖模型來,但是當濾波是在其內部進行的事件是由3dparty的WinForms控制上升。 – Kurtevich

+0

噢,好的。然後,我使用交互命名空間,因爲它需要較少的大量的代碼不是寫新的連接的屬性:' ' – Mashton

相關問題