2017-02-24 96 views
0

我有WPF MVVM應用,在那裏我要傳遞的事件參數到視圖模型,它不工作。我瀏覽了本網站和其他網站上發現的一些類似主題,但沒有結果。WPF和MVVM:傳遞事件參數不工作

這是我在控制內XAML:

<telerik:RadMap> 
<i:Interaction.Triggers> 
    <i:EventTrigger EventName="MouseMove" > 
    <ei:CallMethodAction TargetObject="{Binding}" MethodName="VM.SomeMethod"/> 
    </i:EventTrigger> 
</i:Interaction.Triggers> 
</telerik:RadMap> 

而且我的ViewModel裏面我有方法:

public void SomeMethod(object sender, MouseEventArgs e) 
{ 

} 

當我移動鼠標控制它引發異常說有對該方法來說沒有適當的簽名。

然後,我還試圖用Telerik的的EventToCommandBehavior,像這樣:

<telerik:RadMap> 
<telerik:EventToCommandBehavior ...> 
... 

它抱怨說,Eve​​ntToCommandBehavior不存在。我搜索了一下,發現了這個EventToCommandBehavior,即使在telerik文檔中也是如此。所以我有一個猜想,也許這是一個較新的功能使我Telerik的是,從2010年

無論如何,就如何通過事件參數的視圖模型的任何建議都歡迎。

+0

當使用'EventToCommand'時,你需要''ViewModel'上的'綁定到ICommand'。 [This](https://msdn.microsoft.com/en-us/magazine/dn237302.aspx)可能會有所幫助! –

+0

如果刪除「VM」,該怎麼辦:MethodName =「SomeMethod」? – mm8

+0

我從來沒有使用telerik的mvvm框架,但是如果它像MVVM Light一樣工作,那麼需要設置一個名爲'PassEventArgsToCommand'的屬性。 –

回答

0

this,我讀

被稱爲必須是一個公共方法,它沒有參數和不返回值或公共方法的簽名匹配的事件處理程序的方法。

如果沒有特別需要MouseEventArgs信息,您可以嘗試不帶參數,或用:

public void SomeMethod(object sender, EventArgs e) 
{ 

} 

我2美分...

+0

你的2美分是在最初的話題中提到的,並確認它不起作用 –

+0

我在你的文章中看到的和我所提出的事件參數的類型之間的區別是'MouseEventArgs'在你的情況下, EventArgs'在我的。這是你試過的嗎?事情是,也許使用'MouseEventArg'的限制太多了,預期的類型只是'EventArgs',你可以在事件管理中稍後將其轉換回'MouseEventArgs' –

1

編輯:我應該已經閱讀這個問題更好。綁定表達式的默認根是被綁定的UI元素的DataContext,所以VM.SomeCommand被綁定表達式讀爲DataContext.VM.SomeCommand。 VM.SomeCommand應該改爲SomeCommand,因爲你的視圖的DataContext應該是你的ViewModel。

的Expression Blend的交互結構不支持將事件參數的命令。我會建議使用MVVM框架。

隨着MVVM Light,這布拉德利Uffner提到的,你可能只是這樣做:

<i:Interaction.Triggers> 
    <i:EventTrigger EventName="MouseMove"> 
     <cmd:EventToCommand Command="{Binding Mode=OneWay, Path=SomeCommand}" 
          PassEventArgsToCommand="True" /> 
    </i:EventTrigger> 
</i:Interaction.Triggers> 

但是,如果你反對這個想法的原因之一或其他,你可以嘗試的解決方案討論here。從鏈接

示例代碼:

public sealed class InvokeDelegateCommandAction : TriggerAction<DependencyObject> 
{ 
    /// <summary> 
    /// 
    /// </summary> 
    public static readonly DependencyProperty CommandParameterProperty = 
     DependencyProperty.Register("CommandParameter", typeof(object), typeof(InvokeDelegateCommandAction), null); 

    /// <summary> 
    /// 
    /// </summary> 
    public static readonly DependencyProperty CommandProperty = DependencyProperty.Register(
     "Command", typeof(ICommand), typeof(InvokeDelegateCommandAction), null); 

    /// <summary> 
    /// 
    /// </summary> 
    public static readonly DependencyProperty InvokeParameterProperty = DependencyProperty.Register(
     "InvokeParameter", typeof(object), typeof(InvokeDelegateCommandAction), null); 

    private string commandName; 

    /// <summary> 
    /// 
    /// </summary> 
    public object InvokeParameter 
    { 
     get 
     { 
      return this.GetValue(InvokeParameterProperty); 
     } 
     set 
     { 
      this.SetValue(InvokeParameterProperty, value); 
     } 
    } 

    /// <summary> 
    /// 
    /// </summary> 
    public ICommand Command 
    { 
     get 
     { 
      return (ICommand)this.GetValue(CommandProperty); 
     } 
     set 
     { 
      this.SetValue(CommandProperty, value); 
     } 
    } 

    /// <summary> 
    /// 
    /// </summary> 
    public string CommandName 
    { 
     get 
     { 
      return this.commandName; 
     } 
     set 
     { 
      if (this.CommandName != value) 
      { 
       this.commandName = value; 
      } 
     } 
    } 

    /// <summary> 
    /// 
    /// </summary> 
    public object CommandParameter 
    { 
     get 
     { 
      return this.GetValue(CommandParameterProperty); 
     } 
     set 
     { 
      this.SetValue(CommandParameterProperty, value); 
     } 
    } 

    /// <summary> 
    /// 
    /// </summary> 
    /// <param name="parameter"></param> 
    protected override void Invoke(object parameter) 
    { 
     this.InvokeParameter = parameter; 

     if (this.AssociatedObject != null) 
     { 
      ICommand command = this.ResolveCommand(); 
      if ((command != null) && command.CanExecute(this.CommandParameter)) 
      { 
       command.Execute(this.CommandParameter); 
      } 
     } 
    } 

    private ICommand ResolveCommand() 
    { 
     ICommand command = null; 
     if (this.Command != null) 
     { 
      return this.Command; 
     } 
     var frameworkElement = this.AssociatedObject as FrameworkElement; 
     if (frameworkElement != null) 
     { 
      object dataContext = frameworkElement.DataContext; 
      if (dataContext != null) 
      { 
       PropertyInfo commandPropertyInfo = dataContext 
        .GetType() 
        .GetProperties(BindingFlags.Public | BindingFlags.Instance) 
        .FirstOrDefault(
         p => 
         typeof(ICommand).IsAssignableFrom(p.PropertyType) && 
         string.Equals(p.Name, this.CommandName, StringComparison.Ordinal) 
        ); 

       if (commandPropertyInfo != null) 
       { 
        command = (ICommand)commandPropertyInfo.GetValue(dataContext, null); 
       } 
      } 
     } 
     return command; 
    } 
} 

用法示例從博客:

<ComboBox> 
    <ComboBoxItem Content="Foo option 1" /> 
    <ComboBoxItem Content="Foo option 2" /> 
    <ComboBoxItem Content="Foo option 3" /> 
    <Interactivity:Interaction.Triggers> 
     <Interactivity:EventTrigger EventName="SelectionChanged" > 
      <Presentation:InvokeDelegateCommandAction 
       Command="{Binding SubmitFormCommand}" 
       CommandParameter="{Binding RelativeSource={RelativeSource Self}, Path=InvokeParameter}" /> 
     </Interactivity:EventTrigger> 
    </Interactivity:Interaction.Triggers>     
</ComboBox> 

注:我沒有測試從這個博客的解決方案。