tiempo - wpf c# ejemplos
WPF: manejo de eventos adjuntos personalizados en controles personalizados (1)
No ha publicado todo su código, así que tuve que inferir y armar mi propia versión. Funciona bien para mí. Quizás compare y contraste con su código:
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>
Tengo un evento enrutado declarado como tal (los nombres han sido cambiados para proteger a los inocentes):
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);
}
}
Bastante estándar. En XAML, tengo un DataTemplate que contiene un solo control personalizado. Estoy intentando adjuntar este evento (así como otras propiedades adjuntas) al control:
<DataTemplate ...>
<My:CustomControl
My:DragHelper.IsDragSource="True"
My:DragHelper.DragComplete="DragCompleteHandler" />
</DataTemplate>
Esto no produce los resultados deseados. Específicamente, mientras se llama al código que llama a RaiseEvent () para el evento DragComplete, el controlador nunca se invoca. Ni, de hecho, son los controladores para cualquier otro evento enrutado personalizado que esté conectado en otro lugar en este archivo XAML.
Traté de cambiar el nombre del evento enrutado, e intenté cambiar la plantilla de datos de una con un DataType a una con una x: clave. Esto no produjo ningún cambio visible en el comportamiento.
Sin embargo, si cambio My: CustomControl a cualquier control WPF incorporado, como un TextBlock, los eventos se disparan exactamente como lo haría. De forma similar, si reemplazo mi control personalizado con cualquier otra subclase personalizada de UserControl de mi proyecto, el comportamiento vuelve al estado roto, sin eventos que alguna vez pareció manejarse.
Esto no tiene mucho sentido para mí. ¿Hay algo específico que deba hacer para que este escenario funcione? Parece que no debería importar. Supongo que es posible que haya algo específico que he hecho en todos mis controles personalizados que hace que se rompa el manejo del evento, pero no he visto nada común en los tres o cuatro controles personalizados que he probado hasta ahora.