c# xaml caliburn.micro attached-properties routed-events

c# - utilizando eventos adjuntos con micro mensaje de calibrado.Atar



xaml caliburn.micro (3)

No creo que el analizador para la sintaxis abreviada 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>

Intento utilizar micro mensaje de caliburn para desencadenar un evento adjunto que he creado:

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, agregué 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 nombres completo):

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

intenté establecer el evento de interacción por mi cuenta:

Cuando intenté agregar un activador de evento normal, todo funcionó bien, así que no es mi declaración de evento adjunta:

<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 mal aquí? No hay forma de adjuntar un evento adjunto e invocarlo usando caliburn micro?


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. el desencadenador de evento personalizado se tomó de esa publicación: 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 quieras usar la acción de calibración:

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


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

Código de control infantil detrás:

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

Control infantil XAML:

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

Vista principal

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