2009-08-27 38 views
7

Tôi đã là một sự kiện chuyển tuyên bố như vậy (tên đã được thay đổi để bảo vệ sự vô tội):WPF - Xử lý sự kiện tùy chỉnh gắn trên tùy chỉnh điều khiển

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

thứ Khá chuẩn. Trong XAML, tôi có một DataTemplate chứa một điều khiển tùy chỉnh duy nhất. Tôi đang cố gắng đính kèm sự kiện này (cũng như một số thuộc tính đính kèm khác) vào điều khiển:

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

Điều này không tạo ra kết quả mong muốn. Cụ thể, trong khi mã gọi RaiseEvent() cho sự kiện DragComplete được gọi, thì trình xử lý không bao giờ được gọi. Thực ra, cũng không phải là các trình xử lý cho bất kỳ sự kiện định tuyến tùy chỉnh nào khác được nối ở đâu đó trong tệp XAML này.

Tôi đã thử thay đổi tên của sự kiện được định tuyến và tôi đã thử chuyển đổi mẫu dữ liệu từ một với một DataType thành một với khóa x:. Điều này tạo ra không có thay đổi rõ ràng trong hành vi.

Tuy nhiên, nếu tôi thay đổi My: CustomControl thành bất kỳ điều khiển WPF tích hợp nào, chẳng hạn như TextBlock, các sự kiện được kích hoạt chính xác như tôi sẽ thoát. Tương tự như vậy, nếu tôi thay thế điều khiển tùy chỉnh của mình bằng bất kỳ lớp con UserControl tùy chỉnh nào khác từ dự án của tôi, thì hành vi đó sẽ trở lại trạng thái bị hỏng, không có sự kiện nào từng được xử lý.

Điều này không có ý nghĩa gì đối với tôi. Có điều gì đó cụ thể tôi cần phải làm để có được kịch bản này để làm việc? Có vẻ như nó không quan trọng. Tôi cho rằng có thể có một điều cụ thể mà tôi đã thực hiện trong tất cả các điều khiển tùy chỉnh khiến cho sự kiện xử lý bị hỏng, nhưng tôi chưa thấy bất kỳ điều gì phổ biến trong ba hoặc bốn điều khiển tùy chỉnh mà tôi đã thử cho đến nay.

Trả lời

1

Bạn chưa đăng tất cả mã của mình, vì vậy tôi đã suy ra và đặt cùng phiên bản của riêng mình. Nó hoạt động tốt cho tôi. Có lẽ so sánh và tương phản với mã của bạn:

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

Cảm ơn. Điều khiển tùy chỉnh của tôi có nguồn gốc từ UserControl, nhưng thậm chí chuyển nó sang TextBox như của bạn vẫn còn trưng bày vấn đề cho tôi. Tôi bỏ qua phần còn lại của mã bởi vì tất cả về cơ bản giống như của bạn, ngoại trừ một số thay đổi không gian tên. Tuy nhiên, nó là một phần của một dự án lớn hơn nhiều, vì vậy có thể có một số loại tương tác với một số phong cách toàn cầu hoặc tài nguyên hoặc một cái gì đó tôi không biết điều đó có thể ảnh hưởng đến vấn đề. Tôi sẽ xem những gì tôi có thể làm. –

+1

Được rồi, vì vậy tôi đã bị lừa một chút. Bắt đầu từ ví dụ hoàn chỉnh của bạn, đã làm việc cho tôi, tôi đã thử nhiều thứ khác nhau để biến đổi nó thành trường hợp phi chức năng mà tôi thấy trong dự án lớn hơn của mình. Sau một thời gian, tôi tình cờ gặp một thay đổi rất đơn giản đối với mã cơ sở của bạn để tái tạo sự cố. Nếu tôi thực hiện DragHelper của bạn và di chuyển nó đến một assembly khác được tham chiếu bởi ứng dụng chính và sửa đổi Window1.xaml cho phù hợp (thêm một xmlns: other và user khác: thay vì local :) thì tôi không còn thấy hộp tin nhắn fire khi tôi nhập vào hộp văn bản. : | –

Các vấn đề liên quan