mvvm

2012-12-24 14 views
18

में mousedouble क्लिक कमांड को कैसे बाध्य करें मेरे पास सूचीदृश्य है और जब कोई किसी भी स्थिति में डबल क्लिक करता है तो मैं नई विंडो दिखाना चाहता हूं। लेकिन मेरे पास एमवीवीएम एप्लीकेशन है और मैं xaml फ़ाइल के पीछे कोड में कोई फ़ंक्शन नहीं लेना चाहता, जैसे: How to bind a Command to double-click on a row in DataGrid और इस तरह के कई अन्य नमूने।mvvm

<ListView ... MouseDoubleClick="{Binding myfunction}"> 

धन्यवाद

+0

एक नज़र [यहां] (लो http://stackoverflow.com/questions/4785685/wpf-and-mvvm-binding -वेन्ट्स) माउस घटनाओं के लिए एक एमवीवीएम उदाहरण के लिए। –

उत्तर

22

यह सूची में क्लिक किए गए आइटम के आधार पर कमांड (व्यूमोडेल में) को ट्रिगर करने के लिए एक विधि का एक कामकाजी उदाहरण है। व्यूमोडेल में कमांड को "क्लिक" आइटम को इसके पैरामीटर के रूप में प्राप्त होगा।

मैं टेक्स्टब्लॉक का उपयोग कर रहा हूं। इनपुट बाइंडिंग और यह ब्लेंड एसएमके ब्लैंचमा से जुड़ा हुआ हो सकता है, लेकिन इसके लिए आपको किसी अन्य डीएलएल की आवश्यकता नहीं होगी।

मेरी उदाहरण ViewModel में UserControl के DataContext के लिए बाध्य है, यही कारण है कि मैं अपने TextBlock से ViewModel खोजने के लिए RelativeSource FindAncestor उपयोग करने की आवश्यकता है।

संपादित: TextBlock की चौड़ाईActualWidth ListBox की से जुड़ कर चौड़ाई समस्या ठीक की गई।

बस एक समस्या, डबल क्लिक करें केवल जब तुम TextBlock में पाठ के अंदर क्लिक करें, भले ही स्वयं सूची बहुत व्यापक है काम करेंगे।

<ListView ItemsSource="{Binding Model.TablesView}" Grid.Row="1" 
       SelectedItem="{Binding Model.SelectedTable, Mode=TwoWay}" > 
     <ListView.ItemTemplate> 
      <DataTemplate> 
       <TextBlock Text="{Binding Path=.}" 
        Width="{Binding Path=ActualWidth, 
          RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListView}}}" > 
        <TextBlock.InputBindings> 
         <MouseBinding MouseAction="LeftDoubleClick" Command="{Binding DataContext.MoveItemRightCommand, 
             RelativeSource={RelativeSource FindAncestor, 
             AncestorType={x:Type UserControl}}}" 
             CommandParameter="{Binding .}"/> 
        </TextBlock.InputBindings> 
       </TextBlock> 
      </DataTemplate> 
     </ListView.ItemTemplate> 
    </ListView> 
+0

धन्यवाद @ पीटर –

9

इस (के माध्यम से Blend SDK दोनों स्वतंत्र रूप से उपलब्ध)

System.Windows.Interactivity और Microsoft.Expression.Interactions उपयोग करने के लिए है सबसे आसान तरीका है: मैं viewmodel फ़ाइल में विधि है और इस तरह यह बाध्य करने के लिए चाहते हैं तो अपने दृश्य में निम्नलिखित नामस्थान जोड़कर

xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions" 

अगला, DoubleClick ईवेंट और pa को पकड़ें आदेश करने के लिए इसे ss:

<ListView ..... > 
    <i:Interaction.Triggers> 
     <i:EventTrigger EventName="MouseDoubleClick"> 
      <local:EventToCommand Command="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=DataContext.myfunction}" /> 
     </i:EventTrigger 
    </i:Interaction.Triggers> 
</ListView> 

नोट: EventToCommand इस्तेमाल किया MVVM Light Toolkit से एक है और here डाउनलोड किया जा सकता। यह क्या होता है जैसे ही ईवेंट ट्रिगर होता है, कमांड (myFunction) निष्पादित करता है।

यह धारणा पर आधारित है कि myFunction कमांड DataContext में है जो ListView उपयोगकर्ताओं को है। अन्यथा, EventToCommand के बाध्यकारी को जहां भी आदेश है, संशोधित करें।

+0

मैंने माइक्रोसॉफ्ट.इक्सप्रेस.इंटरक्शन.dll का एक संदर्भ जोड़ा और अब बिल्ड में एक त्रुटि है कि यह डेल एक WPF प्रोजेक्ट में समर्थित नहीं है। वीएस 2013. – Rhyous

+0

यह पता लगाने के लिए कि आपके द्वारा उपयोग किए जाने वाले वैध ईवेंट नाम क्या हैं जैसे EventName = "MouseDoubleClick"? क्योंकि यह इंटेलिजेंस नहीं देता है। –

+0

इसे उत्तर के रूप में चिह्नित किया जाना चाहिए। – Jeb

14

आप Attached Properties का उपयोग किसी भी घटना में आप चाहते बाध्य करने के लिए कर सकते हैं।

MouseDoubleClick के लिए:

namespace Behavior 
{ 
public class MouseDoubleClick 
{ 
    public static DependencyProperty CommandProperty = 
     DependencyProperty.RegisterAttached("Command", 
     typeof(ICommand), 
     typeof(MouseDoubleClick), 
     new UIPropertyMetadata(CommandChanged)); 

    public static DependencyProperty CommandParameterProperty = 
     DependencyProperty.RegisterAttached("CommandParameter", 
              typeof(object), 
              typeof(MouseDoubleClick), 
              new UIPropertyMetadata(null)); 

    public static void SetCommand(DependencyObject target, ICommand value) 
    { 
     target.SetValue(CommandProperty, value); 
    } 

    public static void SetCommandParameter(DependencyObject target, object value) 
    { 
     target.SetValue(CommandParameterProperty, value); 
    } 
    public static object GetCommandParameter(DependencyObject target) 
    { 
     return target.GetValue(CommandParameterProperty); 
    } 
    private static void CommandChanged(DependencyObject target, DependencyPropertyChangedEventArgs e) 
    { 
     Control control = target as Control; 
     if (control != null) 
     { 
      if ((e.NewValue != null) && (e.OldValue == null)) 
      { 
       control.MouseDoubleClick += OnMouseDoubleClick; 
      } 
      else if ((e.NewValue == null) && (e.OldValue != null)) 
      { 
       control.MouseDoubleClick -= OnMouseDoubleClick; 
      } 
     } 
    } 
    private static void OnMouseDoubleClick(object sender, RoutedEventArgs e) 
    { 
     Control control = sender as Control; 
     ICommand command = (ICommand)control.GetValue(CommandProperty); 
     object commandParameter = control.GetValue(CommandParameterProperty); 
     command.Execute(commandParameter); 
    } 
} 
} 

और Xaml में:

<ListBox Behavior:MouseDoubleClick.Command="{Binding ....}" 
      Behavior:MouseDoubleClick.CommandParameter="{Binding ....}"/>