2009-08-27 7 views
7

Mam kierowane zdarzenie zgłoszone jako takiej (imiona zostały zmienione w celu ochrony niewinnych):WPF - zwyczaj obchodzenia załączone wydarzenia na zwyczaju kontroluje

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

dość standardowe rzeczy. W XAML mam DataTemplate, który zawiera jeden niestandardowy formant. Próbuję dołączyć to zdarzenie (jak również niektóre inne dołączone właściwości) do kontrolki:

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

Nie daje to pożądanych rezultatów. W szczególności, gdy wywoływany jest kod wywołujący funkcję RaiseEvent() dla zdarzenia DragComplete, procedura obsługi nigdy nie jest wywoływana. W rzeczywistości nie są to programy obsługi dla żadnych innych niestandardowych zdarzeń routowanych, które są podłączone w innym miejscu tego pliku XAML.

Próbowałem zmienić nazwę zdarzenia routowanego i próbowałem zmienić szablon danych z jednego z DataType na jeden z kluczem x:. Nie spowodowało to widocznych zmian w zachowaniu.

Jednakże, jeśli zmienię My: CustomControl na dowolny wbudowany kontroler WPF, taki jak TextBlock, zdarzenia są uruchamiane dokładnie tak, jak chciałbym to zrobić. Podobnie, jeśli zastąpię kontrolkę niestandardową dowolną inną niestandardową podklasą UserControl z mojego projektu, zachowanie powróci do stanu zepsutego, nigdy nie zdarza się, aby kiedykolwiek zdawało się, że zostanie obsłużony.

To nie ma dla mnie większego sensu. Czy jest coś konkretnego, co muszę zrobić, aby ten scenariusz zadziałał? Wygląda na to, że nie powinno to mieć znaczenia. Przypuszczam, że jest możliwe, że istnieje pewna rzecz, którą zrobiłem we wszystkich moich niestandardowych kontrolkach, które powodują awarię obsługi zdarzeń, ale nie widziałem niczego powszechnego w trzech lub czterech kontrolkach niestandardowych, które próbowałem do tej pory.

Odpowiedz

1

Nie opublikowałeś całego swojego kodu, więc musiałem wywnioskować i złożyć swoją własną wersję. Działa to dla mnie dobrze. Być może porównanie i kontrast do kodu:

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

Dzięki. Moja niestandardowa kontrola została wyprowadzona z UserControl, ale nawet przełączenie jej na TextBox, takie jak twoje, nadal wykazuje problem dla mnie. Pominąłem resztę kodu, ponieważ wszystko jest w zasadzie takie samo jak twoje, z wyjątkiem pewnych zmian w przestrzeni nazw. Jest to jednak część znacznie większego projektu, więc może istnieć jakaś interakcja z jakimś globalnym stylem lub zasobem lub coś, czego nie jestem świadomy, może wpłynąć na ten problem. Zobaczę co da się zrobić. –

+1

Dobra, więc trochę się oszukałem. Zaczynając od pełnego przykładu, który dla mnie działa, próbowałem różnych rzeczy, aby przekształcić go w niefunkcjonalny przypadek, który widzę w moim większym projekcie. Po chwili natknąłem się na bardzo prostą zmianę kodu bazowego, który odtwarza problem. Jeśli weźmiemy twoją implementację DragHelper i przeniesiemy ją do innego zestawu, do którego odwołuje się główna aplikacja i odpowiednio zmodyfikujemy Window1.xaml (dodaj xmlns: inny i użytkownik inny: zamiast lokalnego :) to już nie widzę pożaru okna komunikatu kiedy wpisuję w polu tekstowym. : | –

Powiązane problemy