2009-08-27 11 views
7

मैं एक कराई घटना इस तरह के रूप में घोषित किया (नाम मासूम की रक्षा करने के लिए बदल दिया गया है) है:WPF - कस्टम पर कस्टम जुड़ी घटनाओं से निपटने को नियंत्रित करता है

public class DragHelper : DependencyObject { 
    public static readonly RoutedEvent DragCompleteEvent = EventManager.RegisterRoutedEvent(
     "DragComplete", 
     RoutingStrategy.Bubble, 
     typeof(DragRoutedEventHandler), 
     typeof(DragHelper) 
    ); 

    public static void AddDragCompleteHandler(DependencyObject dependencyObject, DragRoutedEventHandler handler) { 
     UIElement element = dependencyObject as UIElement; 
     if (element != null) { 
      element.AddHandler(DragCompleteEvent, handler); 
     } 
    } 

    public static void RemoveDragCompleteHandler(DependencyObject dependencyObject, DragRoutedEventHandler handler) { 
     UIElement element = dependencyObject as UIElement; 
     if (element != null) { 
      element.RemoveHandler(DragCompleteEvent, handler); 
     } 
    } 

सुंदर मानक सामान। एक्सएएमएल में, मेरे पास डेटा टेम्पलेट है जिसमें एक कस्टम नियंत्रण होता है। मैं नियंत्रण करने के लिए इस घटना (और साथ ही कुछ अन्य संलग्न गुण) संलग्न करने के लिए प्रयास कर रहा हूँ:

<DataTemplate ...> 
    <My:CustomControl 
     My:DragHelper.IsDragSource="True" 
     My:DragHelper.DragComplete="DragCompleteHandler" /> 
</DataTemplate> 

यह वांछित परिणाम का उत्पादन करने में विफल रहता है। विशेष रूप से, जबकि ड्रैगकंपलेट ईवेंट के लिए RaiseEvent() को कॉल करने वाला कोड कहा जाता है, हैंडलर कभी नहीं बुलाया जाता है। न ही, वास्तव में, किसी भी अन्य कस्टम रूटेड घटनाओं के लिए हैंडलर हैं जो इस एक्सएएमएल फ़ाइल में कहीं और झुका हुआ हैं।

मैंने रूटेड घटना का नाम बदलने की कोशिश की, और मैंने डेटा टेम्पलेट को डेटाटाइप के साथ एक एक्स: कुंजी के साथ स्विच करने का प्रयास किया। इसने व्यवहार में कोई दृश्य परिवर्तन नहीं किया।

हालांकि, अगर मैं अपने: कस्टमकंट्रोल को किसी भी अंतर्निहित WPF नियंत्रण में बदलता हूं, जैसे कि टेक्स्टब्लॉक, ईवेंट ठीक से निकाल दिए जाते हैं जैसा कि मैं निष्कासित करता हूं। इसी तरह, अगर मैं अपने प्रोजेक्ट से किसी भी अन्य कस्टम उपयोगकर्ता नियंत्रण सबक्लास के साथ अपने कस्टम नियंत्रण को प्रतिस्थापित करता हूं, तो व्यवहार टूटने वाले, नो-इवेंट-कभी-कभी-प्रतीत होने वाले हाथ से चलने वाले राज्य में बदल जाता है।

यह मेरे लिए पूरी तरह से समझ में नहीं आता है। क्या इस परिदृश्य को काम करने के लिए मुझे कुछ विशिष्ट करने की ज़रूरत है? ऐसा लगता है कि इससे कोई फर्क नहीं पड़ता। मुझे लगता है कि यह संभव है कि मेरे सभी कस्टम नियंत्रणों में एक विशिष्ट चीज है जो ईवेंट को तोड़ने का कारण बनती है, लेकिन मैंने अभी तक तीन या चार कस्टम नियंत्रणों में कुछ भी सामान्य नहीं देखा है।

उत्तर

1

आपने अपना पूरा कोड पोस्ट नहीं किया है, इसलिए मुझे अपना खुद का संस्करण अनुमान लगाया और रखा। यह मेरे लिए ठीक काम करता है। शायद तुलना और कॉन्ट्रास्ट अपने कोड:

Window1.xaml.cs:

using System.Windows; 
using System.Windows.Controls; 

namespace WpfApplication1 
{ 
    public partial class Window1 : Window 
    { 
     public Window1() 
     { 
      InitializeComponent(); 
     } 

     private void DragCompleteHandler(object sender, RoutedEventArgs e) 
     { 
      MessageBox.Show("YEP"); 
     } 
    } 

    public class CustomControl : TextBox 
    { 
    } 

    public class DragHelper : DependencyObject 
    { 
     public static readonly DependencyProperty IsDragSourceProperty = DependencyProperty.RegisterAttached("IsDragSource", 
      typeof(bool), 
      typeof(DragHelper), 
      new FrameworkPropertyMetadata(OnIsDragSourceChanged)); 

     public static bool GetIsDragSource(DependencyObject depO) 
     { 
      return (bool)depO.GetValue(IsDragSourceProperty); 
     } 

     public static void SetIsDragSource(DependencyObject depO, bool ids) 
     { 
      depO.SetValue(IsDragSourceProperty, ids); 
     } 

     public static readonly RoutedEvent DragCompleteEvent = EventManager.RegisterRoutedEvent(
      "DragComplete", 
      RoutingStrategy.Bubble, 
      typeof(RoutedEventHandler), 
      typeof(DragHelper) 
     ); 

     public static void AddDragCompleteHandler(DependencyObject dependencyObject, RoutedEventHandler handler) 
     { 
      UIElement element = dependencyObject as UIElement; 
      if (element != null) 
      { 
       element.AddHandler(DragCompleteEvent, handler); 
      } 
     } 

     public static void RemoveDragCompleteHandler(DependencyObject dependencyObject, RoutedEventHandler handler) 
     { 
      UIElement element = dependencyObject as UIElement; 
      if (element != null) 
      { 
       element.RemoveHandler(DragCompleteEvent, handler); 
      } 
     } 

     private static void OnIsDragSourceChanged(DependencyObject depO, DependencyPropertyChangedEventArgs e) 
     { 
      (depO as TextBox).TextChanged += delegate 
      { 
       (depO as TextBox).RaiseEvent(new RoutedEventArgs(DragCompleteEvent, null)); 
      }; 
     } 
    } 
} 

Window1.xaml:

<Window x:Class="WpfApplication1.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:WpfApplication1" 
    Title="Window1" Height="300" Width="300"> 
    <Window.Resources> 
     <DataTemplate x:Key="Test"> 
      <local:CustomControl 
       local:DragHelper.IsDragSource="True" 
       local:DragHelper.DragComplete="DragCompleteHandler" /> 
     </DataTemplate> 
    </Window.Resources> 

    <ContentControl ContentTemplate="{StaticResource Test}"/> 
</Window> 
+0

धन्यवाद। मेरा कस्टम नियंत्रण UserControl से लिया गया था, लेकिन इसे आपके जैसे टेक्स्टबॉक्स पर भी स्विच करना अभी भी मेरे लिए समस्या प्रदर्शित करता है। मैंने बाकी कोड को छोड़ दिया क्योंकि यह मूल रूप से आपके जैसा ही है, कुछ नामस्थान परिवर्तनों को छोड़कर। हालांकि, यह एक बहुत बड़ी परियोजना का हिस्सा है, इसलिए कुछ वैश्विक शैली या संसाधन के साथ कुछ प्रकार की बातचीत हो सकती है या मुझे पता नहीं है कि इससे समस्या प्रभावित हो सकती है। में देखता हूँ में क्या कर सकता हूँ। –

+1

ठीक है, इसलिए मैंने थोड़ा सा मूर्ख बना दिया है। आपके पूरे उदाहरण से शुरू हुआ, जिसने मेरे लिए काम किया, मैंने विभिन्न चीजों को गैर-कार्यात्मक मामले में बदलने की कोशिश की जो मैं अपने बड़े प्रोजेक्ट में देख रहा हूं। थोड़ी देर बाद, मैंने आपके बेस कोड में एक बहुत ही सरल परिवर्तन पर ठोकर खाई जो समस्या को पुन: उत्पन्न करता है। यदि मैं आपके ड्रैगहेल्पर कार्यान्वयन को लेता हूं और इसे एक अलग असेंबली में ले जाता हूं जिसे मुख्य एप्लिकेशन द्वारा संदर्भित किया जाता है और उसके अनुसार Window1.xaml संशोधित करता है (एक xmlns जोड़ें: अन्य और उपयोगकर्ता अन्य: स्थानीय के बजाय :) तो अब मुझे संदेश बॉक्स आग नहीं दिखाई देगी जब मैं टेक्स्टबॉक्स में टाइप करता हूं। : | –

संबंधित मुद्दे