2009-08-27 18 views
7

kontrol eder:WPF - özel üzerindeki özel ekli olayları işleme Böyle olarak ilan bir yönlendirilmiş olay (isimlerle masum korumak için değiştirilmiştir) olan

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); 
     } 
    } 

Oldukça standart şeyler. XAML'de, tek bir özel denetim içeren bir DataTemplate var. Kontrolde bu olayı (yanı sıra diğer bazı ekli özellikleri) eklemek için çalışılıyor:

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

Bu istenen sonuçları elde etmek için başarısız olur. Özellikle, DragComplete olayı için RaiseEvent() çağrılan kod çağrılırken, işleyici asla çağrılmaz. Aslında, bu XAML dosyasında başka bir yere bağlanan diğer özel yönlendirilmiş olayların işleyicileri de yoktur.

Ben yönlendirilmiş olayın adını değiştirerek çalıştı ve bir x ile birine bir DataType ile birinden veri şablonunu değiştirme çalıştı: Key. Bu davranışta gözle görülür bir değişiklik yaratmadı.

Ancak, My değiştirirseniz: Herhangi yerleşik WPF denetimi, böyle bir TextBlock olarak, olaylar ı exect gibi aynen ateşlenir için CustomControl. Benzer şekilde, özel denetimimi projemden başka bir özel UserControl alt sınıfıyla değiştirirsem, davranış, bozuk, olaylara hiç görünmeyen ele alma durumu durumuna döner.

Bu benim için mantıklı bir sürü yapmak değildir. Bu senaryoyu işe almak için yapmam gereken belirli bir şey var mı? Önemli olmamalı gibi görünüyor. Tüm özel denetimlerimde, olay işlemenin kesilmesine neden olan belirli bir şey olabileceğini düşünüyorum, ancak şimdiye kadar denediğim üç veya dört özel denetimde ortak bir şey görmedim.

cevap

1

Tüm kodunuzu yayınlanmıştır değil, bu yüzden anlaması ve birlikte kendi versiyonunu koymak zorunda kaldı. Benim için iyi çalışıyor. Belki koduna karşılaştırmak ve kontrast:

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

teşekkür ederiz. Benim özel denetim UserControl türetilmiş, ama seninki hala benim için problem sergiler gibi hatta TextBox onu geçiş oldu. Kodun geri kalanını ihmal ettim, çünkü bazı isim-alanı değişiklikleri dışında, temelde sizinkiyle aynı. Ancak, çok daha büyük bir projenin bir parçası olduğu için, bazı global tarz veya kaynaklarla bir çeşit etkileşim olabilir ya da sorunu etkileyebileceğinin farkında olmadığım bir şey olabilir. Ne yapabileceğimi göreceğim. –

+1

Tamam, bu yüzden biraz kandırdım. Benim için çalıştığım tam örneğinizden başlayarak, daha büyük projemde gördüğüm işlevsel olmayan duruma dönüştürmek için çeşitli şeyler denedim. Bir süre sonra, sorunu yeniden üreten temel kodunuza çok basit bir değişiklik yaptım. DragHelper uygulamanızı alıp ana uygulama tarafından başvurulan farklı bir gruba taşıyıp Window1.xaml dosyasını buna göre değiştirirseniz (xmlns ekleyin: diğer ve kullanıcı diğer: yerel :) yerine artık ileti kutusu yangını göremiyorum metin kutusuna yazdığımda. : | –

İlgili konular