2011-12-06 10 views
13

Sto cercando di utilizzare Caliburn micro messaggio per attivare un evento collegato che ho creato:utilizzando gli eventi collegati al 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; 
    } 
} 

In XAML stesso ho aggiunto la seguente linea:

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

Gli helper fanno riferimento allo spazio dei nomi corretto. Ho provato anche altre versioni che non sono riusciti (spazio dei nomi completo):

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

cercato di impostare l'evento interazione da solo:

Quando ho provato ad aggiungere un evento normale innescare tutto ha funzionato bene, quindi non è la mia dichiarazione evento allegata:

<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> 

Cosa sto facendo wro qui? Non c'è modo di allegare un evento allegato e invocarlo usando caliburn micro?

risposta

12

finalmente ho capito il problema e la soluzione. Il problema è che system.windows.interactiviy.EventTrigger non supporta eventi collegati. Caliburn micro lo usa per le azioni quindi il mio evento allegato non ha funzionato. La soluzione era scrivere un trigger di evento personalizzato e utilizzare la microazione caliburn in modo esplicito. il grilletto evento personalizzato è stato preso da quel post: 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; } 
} 

e poi quando si desidera utilizzare l'azione 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

Non penso che il parser per la sintassi Message.Attach abbreviata supporti eventi collegati. Ma perché non aggiungere semplicemente ActionMessage alle azioni di 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

ho provato, ma il messaggio azione Caliburn è applicabile solo come azione di sistema .finestre. interattività.Event trigger e non quello normale. per essere onesti non sono sicuro di quale sia la differenza tra il 2. Non è stato possibile avviare il mio evento utilizzando il trigger system.windows.interactivity.event. – Clueless

0

Hai provato questo?

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

Avevo bisogno di inviare un evento da un controllo figlio ai genitori ViewModel, e ha funzionato bene per me. Pubblicherò qualche codice di esempio, forse aiuterà qualcuno a uscire!

Child Control codebehind: controllo

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

Bambino XAML: vista

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

principale:

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