2010-05-12 416 views
2

我有一個具有事件的自定義控件。 我有一個使用該自定義控件的窗口。 窗口綁定到視圖模型。 我想從自定義控件直接到我的viewmodel上的ICommand事件。 我明顯在這裏密集,因爲我無法弄清楚如何做到這一點。任何援助是最受歡迎的。將自定義WPF控件中的事件綁定到ViewModel中的命令

謝謝

回答

2

如果它是一次性的,你可以使用一個簡單的事件處理程序:

<some:CustomControl SuperDuper="OnSuperDuper" /> 

與後面的代碼

private void OnSuperDuper(object sender, EventArgs e) 
{ 
    _theCommand.Execute(null, (IInputElement)sender); 
} 

如果您想在此多次對我會的特定事件做使用附加屬性。

<some:CustomControl my:AttachedEvents.SuperDuperCommand="{Binding TheCommand}" /> 

其中附加屬性很簡單:

// use propa snippet to build this quickly 
public static ICommand GetSuperDuperCommand(DependencyObject obj) { return (ICommand)obj.GetValue(SuperDuperCommandProperty); } 
public static void SetSuperDuperCommand(DependencyObject obj, ICommand value) { obj.SetValue(SuperDuperCommandProperty, value); } 
public static readonly DependencyProperty SuperDuperCommandProperty = DependencyProperty.RegisterAttached("SuperDuperCommand", typeof(ICommand), typeof(AttachedEvents), new PropertyMetadata 
{ 
    PropertyChangedCallback = (obj, e) => 
    { 
    if(oldCommand==null) ((CustomControl)obj).SuperDuper += OnSuperDuper; 
    if(newCommand==null) ((CustomControl)obj).SuperDuper -= OnSuperDuper; 
    } 
}); 

private void OnSuperDuper(object sender, EventArgs e) 
{ 
    var control = (CustomControl)sender; 
    GetSuperDuperCommand(sender).Execute(null, sender)); 
} 

您可以進一步推廣此使用的MarkupExtension對任何事件映射到任何命令。這裏的想法:

<some:CustomControl SuperDuper="{lib:CommandWrapper {Binding TheCommand}}" /> 

的代碼是這樣的:

public class CommandWrapper : MarkupExtension 
{ 
    public BindingBase CommandBinding { get; set; } 

    public CommandWrapper() {} 
    public CommandWrapper(BindingBase commandBinding) { CommandBinding = commandBinding; } 

    public object ProvideValue(IServiceProvider serviceProvider) 
    { 
    return new EventHandler((obj, e) => 
    { 
     // Evaluate CommandBinding against obj, fire command 
    }); 
    } 
} 

可以充實細節。請注意,不是簡單地說「新的EventHandler」,您可能希望將實際的事件處理程序類型傳遞給CommandWrapper,並使用反射來構造相應的代理。

我不完全確定XAML解析器會讓您使用MarkupExtension設置事件,所以最後的解決方案實際上可能不會實現這一點。但是,如果沒有,也可以用像這樣的附加屬性組合:

這肯定會工作:CommandWrapper.Add將被標記擴展創建的CommandWrapper接收事件名稱,可以建立相應的映射。