2011-12-06 19 views
13

Estoy intentando utilizar mensaje de micro Caliburn para activar un evento adjunto que he creado:el uso de eventos conectados con Caliburn micro Message.Attach

public static class DataChanging 
{ 

    public delegate void DataChangingEventHandler(object sender, DataChangingEventArgs e); 
    public static readonly RoutedEvent ChangingEvent = 
     EventManager.RegisterRoutedEvent("Changing", 
             RoutingStrategy.Bubble, 
             typeof(DataChangingEventHandler), 
             typeof(DataChanging)); 

    public static void AddChangingHandler(DependencyObject o, DataChangingEventHandler handler) 
    { 
     ((UIElement)o).AddHandler(DataChanging.ChangingEvent, handler); 
    } 
    public static void RemoveChangingHandler(DependencyObject o, DataChangingEventHandler handler) 
    { 
     ((UIElement)o).RemoveHandler(DataChanging.ChangingEvent, handler); 
    } 

    public static bool GetActivationMode(DependencyObject obj) 
    { 
     return (bool)obj.GetValue(ActivationModeProperty); 
    } 
    public static void SetActivationMode(DependencyObject obj, bool value) 
    { 
     obj.SetValue(ActivationModeProperty, value); 
    } 
    public static readonly DependencyProperty ActivationModeProperty = 
     DependencyProperty.RegisterAttached("ActivationMode", 
              typeof(bool), 
              typeof(DataChanging), 
              new FrameworkPropertyMetadata(false, 
                      HandleActivationModeChanged)); 

    private static void HandleActivationModeChanged(DependencyObject target, DependencyPropertyChangedEventArgs e) 
    { 
     var dataGrid = target as XamDataGrid; 
     if (dataGrid == null) // if trying to attach to something else than a datagrid, just ignore 
      return; 
     if ((bool)e.NewValue) 
     { 
      dataGrid.RecordDeactivating += selector_RecordDeactivating; 
     } 
     else 
     { 
      dataGrid.RecordDeactivating -= selector_RecordDeactivating; 
     } 
    } 

    static void selector_RecordDeactivating(object sender, RecordDeactivatingEventArgs e) 
    { 

     var args = new DataChangingEventArgs(DataChanging.ChangingEvent,sender) 
         { 
          Data = ((DataRecord) e.Record).DataItem, 
          ShouldCancelChange = false 
         }; 
     (sender as UIElement).RaiseEvent(args); 
     e.Cancel = args.ShouldCancelChange; 
    } 
} 

En el propio XAML añadí la siguiente línea:

cal:Message.Attach="[Helpers:DataChanging.Changing] = [Action SelectedDataChanged($eventArgs)]" 

Los ayudantes se refieren al espacio de nombres correcto. También probé otras versiones que fallaron (espacio de nombre completo):

cal:Message.Attach="[clr-namespace:RTF.Client.UI.Helpers.DataChanging.Changing] = [Action SelectedDataChanged($eventArgs)]" 

trató de establecer el evento de interacción por mí mismo:

Cuando He intentado añadir un evento normal desencadenar todo funcionaba bien, por lo que no es mi declaración de evento adjunto:

<EventTrigger RoutedEvent="Helpers:DataChanging.Changing"> 
        <EventTrigger.Actions> 
         <BeginStoryboard x:Name="sb"> 
          <Storyboard x:Name="dsf"> 
           <Storyboard x:Name="myStoryboard"> 
            <BooleanAnimationUsingKeyFrames Storyboard.TargetName="SSS" Storyboard.TargetProperty="IsChecked"> 
             <DiscreteBooleanKeyFrame KeyTime="00:00:00" Value="False" /> 
            </BooleanAnimationUsingKeyFrames> 
           </Storyboard> 
          </Storyboard> 
         </BeginStoryboard> 
        </EventTrigger.Actions> 
       </EventTrigger> 

¿Qué estoy haciendo? ng aquí? No hay forma de adjuntar un evento adjunto e invocarlo utilizando caliburn micro?

Respuesta

12

finalmente entiendo el problema y la solución. El problema es que system.windows.interactiviy.EventTrigger no admite eventos adjuntos. Caliburn micro lo usa para acciones, por lo que mi evento adjunto no funcionó. La solución fue escribir un desencadenador de evento personalizado y usar la microactuación de calibración de una manera explícita. la activación de un evento a medida fue tomada a partir de ese mensaje: http://joyfulwpf.blogspot.com/2009/05/mvvm-invoking-command-on-attached-event.html?showComment=1323674885597#c8041424175408473805

public class RoutedEventTrigger : EventTriggerBase<DependencyObject> 
{ 
    RoutedEvent _routedEvent; 
    public RoutedEvent RoutedEvent 
    { 
     get { return _routedEvent; } 
     set { _routedEvent = value; } 
    } 

    public RoutedEventTrigger() { } 
    protected override void OnAttached() 
    { 
     Behavior behavior = base.AssociatedObject as Behavior; 
     FrameworkElement associatedElement = base.AssociatedObject as FrameworkElement; 
     if (behavior != null) 
     { 
      associatedElement = ((IAttachedObject)behavior).AssociatedObject as FrameworkElement; 
     } 
     if (associatedElement == null) 
     { 
      throw new ArgumentException("Routed Event trigger can only be associated to framework elements"); 
     } 
     if (RoutedEvent != null) 
     { associatedElement.AddHandler(RoutedEvent, new RoutedEventHandler(this.OnRoutedEvent)); } 
    } 
    void OnRoutedEvent(object sender, RoutedEventArgs args) 
    { 
     base.OnEvent(args); 
    } 
    protected override string GetEventName() { return RoutedEvent.Name; } 
} 

y luego, cuando desea utilizar la acción Caliburn:

<i:Interaction.Triggers> 
       <!--in the routed event property you need to put the full name space and event name--> 
       <Helpers:RoutedEventTrigger RoutedEvent="Helpers:DataChanging.Changing"> 
        <cal:ActionMessage MethodName="SelectedDataChanged"> 
         <cal:Parameter Value="$eventargs" /> 
        </cal:ActionMessage> 
       </Helpers:RoutedEventTrigger> 
</i:Interaction.Triggers> 
0

No creo que el analizador para la sintaxis acortada de Message.Attach admita eventos adjuntos. ¿Pero por qué no simplemente agrega el ActionMessage directamente a las Acciones del EventTrigger?

<EventTrigger RoutedEvent="Helpers:DataChanging.Changing"> 
    <EventTrigger.Actions> 
     <!-- new part --> 
     <cal:ActionMessage MethodName="SelectedDataChanged"> 
      <cal:Parameter Value="$eventargs" /> 
     </cal:ActionMessage> 
     <!-- /new part --> 
     <BeginStoryboard x:Name="sb"> 
      <Storyboard x:Name="dsf"> 
       <Storyboard x:Name="myStoryboard"> 
        <BooleanAnimationUsingKeyFrames Storyboard.TargetName="SSS" Storyboard.TargetProperty="IsChecked"> 
         <DiscreteBooleanKeyFrame KeyTime="00:00:00" Value="False" /> 
        </BooleanAnimationUsingKeyFrames> 
       </Storyboard> 
      </Storyboard> 
     </BeginStoryboard> 
    </EventTrigger.Actions> 
</EventTrigger> 
+0

lo probé, pero el mensaje de acción Caliburn sólo es aplicable como la acción de sistema .windows. interactividad. Evento desencadenante y no el normal. para ser sincero, no estoy seguro de cuál es la diferencia entre el 2. No pude iniciar mi evento utilizando el disparador system.windows.interactivity.event. – Clueless

0

Has probado esto?

cal:Message.Attach="[Event Changing] = [Action SelectedDataChanged($eventArgs)]" 

Necesitaba enviar un evento desde un control secundario al ViewModel de los padres, y funcionó bien para mí. Voy a publicar un código de ejemplo tal vez ayude a alguien. CodeBehind

Child Control: Control

public partial class MyControl : UserControl 
{ 
    public MyControl() 
    { 
     InitializeComponent(); 
    } 

    #region Routed Events 

    public static readonly RoutedEvent ControlClosedEvent = EventManager.RegisterRoutedEvent(
     "ControlClosed", 
     RoutingStrategy.Bubble, 
     typeof(RoutedEventHandler), 
     typeof(MyControl)); 

    public event RoutedEventHandler ControlClosed 
    { 
     add { AddHandler(ControlClosedEvent, value); } 
     remove { RemoveHandler(ControlClosedEvent, value); } 
    } 

    #endregion Routed Events 

    private void Close(object sender, RoutedEventArgs e) 
    { 
     var rea = new RoutedEventArgs(ControlClosedEvent); 
     RaiseEvent(rea); 
    } 
} 

Niño XAML: Vista

<Button Grid.Row="1" Grid.Column="0" 
     Content="Close Me!" Height="50" 
     Click="Close" /> 

Padres:

<userControls:MyControl cal:Message.Attach="[Event ControlClosed] = [Action ClosePopup]" /> 
Cuestiones relacionadas