2011-12-06 15 views
13

Próbuję użyć Caliburn mikro wiadomość do wyzwalania załączony zdarzenie, które stworzyłem:używając załączonego wydarzenia z Caliburn mikro 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; 
    } 
} 

W samej XAML I dodaje następujący wiersz:

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

Pomocnicy odnoszą się do właściwej przestrzeni nazw. Próbowałem również inne wersje, które nie powiodło się (pełne nazw):

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

próbowano ustawić zdarzenie interakcji przez siebie:

Kiedy próbowałem dodając normalne zdarzenie wywoła wszystko działało dobrze, więc nie jest to moja dołączona deklaracja zdarzenia:

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

Co ja robię Wro Tutaj? Nie można podłączyć dołączonego zdarzenia i wywołać go za pomocą narzędzia caliburn micro?

Odpowiedz

12

w końcu rozumiem problem i rozwiązanie. Problem polega na tym, że system.windows.interactiviy.EventTrigger nie obsługuje dołączonych zdarzeń. Caliburn micro używa go do akcji, więc moje dołączone wydarzenie nie działało. Rozwiązaniem było napisanie spersonalizowanego wyzwalacza zdarzeń i użycie akcji micro calurn w jawny sposób. dostosowana wyzwalania zdarzenie zostało zrobione z tego postu: 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; } 
} 

a następnie, gdy chcesz użyć działania 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

Nie sądzę, że analizator składni skróconej wiadomości. Składnia obsługuje obsługiwane zdarzenia. Ale dlaczego po prostu nie dodasz ActionMessage bezpośrednio do akcji 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

Próbowałem, ale wiadomość działanie Caliburn ma zastosowanie jedynie jako działanie na układ .windows. wyzwalacz interactivity.Event, a nie normalny. szczerze mówiąc nie jestem pewien jaka jest różnica między 2. Nie byłem w stanie uruchomić mojego zdarzenia przy użyciu wyzwalacza system.windows.interactivity.event. – Clueless

0

Próbował pan jest?

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

Musiałem wysłać zdarzenie z kontroli nad dzieckiem do rodziców ViewModel i działało dobrze dla mnie. Opublikuję przykładowy kod, może to komuś pomóc! codebehind

Child Control: XAML kontrola

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

dziecka: widok

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

nadrzędny:

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