0

我用谷歌搜索了这个问题,但无法收集任何信息,我想知道附加行为是否有可能处理附加事件?

我有一个在类中声明的事件和一个附加到 TextBox 控件的行为,单击按钮时将引发该事件。我在我的行为中添加了这个事件的处理程序,并在事件处理程序中编写了逻辑,但它没有被执行。所以,我想知道附加行为是否有可能处理附加事件?

class ResetInputEventClass
{
    public static readonly RoutedEvent ResetInputEvent =  EventManager.RegisterRoutedEvent("ResetInput",
      RoutingStrategy.Bubble,
      typeof(RoutedEventHandler),
      typeof(ResetInputEventClass));

    public static void AddResetInputEventHandler(DependencyObject d, RoutedEventHandler handler)
    {
        UIElement uie = d as UIElement;
        if (uie == null)
        {
            return;
        }
        uie.AddHandler(ResetInputEventClass.ResetInputEvent, handler);
    }

    public static void RemoveResetInputEventHandler(DependencyObject d, RoutedEventHandler handler)
    {
        UIElement uie = d as UIElement;
        if (uie == null)
        {
            return;
        }
        uie.RemoveHandler(ResetInputEventClass.ResetInputEvent, handler);
    }
}

那是我的事件类,这就是我在行为中处理它的方式

public class MyBehavior : Behavior<TextBoxBase>
{
    public MyBehavior()
    {
        // Insert code required on object creation below this point.

    }        

    protected override void OnAttached()
    {
        base.OnAttached();
        // Insert code that you would want run when the Behavior is attached to an object.
        ResetInputEventClass.AddResetInputEventHandler(AssociatedObject, OnResetInputEvent);
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        // Insert code that you would want run when the Behavior is removed from an object.
        ResetInputEventClass.RemoveResetInputEventHandler(AssociatedObject, OnResetInputEvent);
    }

    private void OnResetInputEvent(Object o, RoutedEventArgs e)
    {
        //Logic
    }
}

这是我的 XAML 代码:

<Grid x:Name="LayoutRoot">
    <StackPanel>
        <TextBox Margin="5" Text="Bye" TextWrapping="Wrap" Width="150">
            <i:Interaction.Behaviors>
                <local:MyBehavior/>
            </i:Interaction.Behaviors>
        </TextBox>
        <TextBox Margin="5" Text="Bye" TextWrapping="Wrap" Width="150">
            <i:Interaction.Behaviors>
                <local:MyBehavior/>
            </i:Interaction.Behaviors>
        </TextBox>
        <Button Name="MyButton" Content="Save" Width="50" Height="25" Click="MyButton_Click"/>
    </StackPanel>
</Grid>

我在按钮的点击事件中引发事件

private void MyButton_Click(object sender, RoutedEventArgs e)
{
    RoutedEventArgs eventArgs = new RoutedEventArgs(ResetInputEventClass.ResetInputEvent,e.OriginalSource);
    RaiseEvent(eventArgs);
}
4

2 回答 2

5

你的问题很简单。文本框已为该事件注册,但文本框的父级正在引发它。因此,处理程序永远不会被调用。您可以更改事件以使其成为隧道事件而不是冒泡事件。或者您可以处理您的文本框(在后面的代码中给它一个名称和引用)。并让它引发事件。

<Grid x:Name="LayoutRoot">
<StackPanel>
<TextBox Margin="5" x:Name="byeTextBox" Text="Bye" TextWrapping="Wrap" Width="150">
                    <i:Interaction.Behaviors>
                        <local:MyBehavior/>
                    </i:Interaction.Behaviors>
                </TextBox>
<Button Name="MyButton" Content="Save" Width="50" Height="25" Click="MyButton_Click"/>
</StackPanel>
</Grid>

您的代码隐藏应如下所示

private void MyButton_Click(object sender, RoutedEventArgs e)
        {
            RoutedEventArgs eventArgs = new RoutedEventArgs(ResetInputEventClass.ResetInputEvent,e.OriginalSource);
            byeTextBox.RaiseEvent(eventArgs);
        }

那应该可以解决您的问题。

于 2013-06-14T20:56:30.423 回答
3

当然这是可能的。给我看你的 XAML,我会告诉你附加的事件如何触发附加的行为。

编辑

我不明白为什么你需要使用附加行为和附加事件,因为你可以在代码后面做所有事情。

以下是如何在后面的代码中执行所有操作:

这是没有附加属性的 XAML:

<Grid>
        <StackPanel>
            <TextBox x:Name="txtBox" Margin="5" Text="Bye" TextWrapping="Wrap" Width="150"/>
            <Button Name="MyButton" Content="Save" Width="50" Height="25" Click="MyButton_Click"/>
        </StackPanel>
</Grid>

这是后面的代码。

    public MainWindow()
    {
        InitializeComponent();
    }

    private void MyButton_Click(object sender, RoutedEventArgs e)
    {
        this.txtBox.Text = "hello";
    }

因为你已经设置了 Name 属性TextBoxButton你可以从 Window.cs 后面的代码中访问它们,你可以轻松地编写你的处理程序。

以下是使用附加属性执行所有操作的方法:

这是带有附加属性的解决方案的新 XAML。我必须创建我的自定义交互,因为您使用的是 Expression Blend 或 silverlight 而不是纯 WPF。

<Grid x:Name="LayoutRoot">
        <StackPanel i:Interaction.Behaviour="True">
            <TextBox x:Name="txtBox" Margin="5" Text="Bye" TextWrapping="Wrap" Width="150"/>
            <Button Name="MyButton" Content="Save" Width="50" Height="25" Click="MyButton_Click"/>
        </StackPanel>
    </Grid>

我必须设置行为,True因为默认值是false,当值不等于旧时,将使用我的自定义逻辑调用属性更改事件,如下所示:

private void MyButton_Click(object sender, RoutedEventArgs e)
    {
        RoutedEventArgs eventArgs = new RoutedEventArgs(ResetInputEventClass.ResetInputEvent,e.OriginalSource);
        RaiseEvent(eventArgs);
    }

 public class Interaction : DependencyObject
{
    // Using a DependencyProperty as the backing store for Behaviour.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty BehaviourProperty =
        DependencyProperty.RegisterAttached("Behaviour", typeof(bool), typeof(Interaction), new PropertyMetadata(false, new PropertyChangedCallback(OnBehaviourChanged)));

    private static void OnBehaviourChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        StackPanel sp = (StackPanel)d;
        sp.Dispatcher.BeginInvoke(new Action(() =>
        {
            TextBox tb =  VisualTreeHelper.GetChild(sp, 0) as TextBox;


            ResetInputEventClass.AddResetInputHandler(sp, new RoutedEventHandler((o, a) =>
            {
                // Do here whatever you want, call your custom expressions.
                tb.Text = "hello";
            }));

        }), System.Windows.Threading.DispatcherPriority.Background);
    }
}

内部属性更改事件将被调用,正如我在更改falsetrue. 我通过告诉调度程序在应用程序处于后台时执行我的代码来等到一切都被初始化。然后我找到并注入在您触发事件TextBox时将调用的处理程序。ResetInput

这是一个非常复杂的解决方案,但它适用于附加事件和附加属性。

我强烈建议您在这种情况下使用背后的代码。

你在ResetInputEventClass课堂上也犯了一个错误。添加和删​​除方法拼写不正确。

你应该这样写它们:

public static void AddResetInputHandler(DependencyObject d, RoutedEventHandler handler)
    {
        UIElement uie = d as UIElement;
        if (uie == null)
        {
            return;
        }
        uie.AddHandler(ResetInputEventClass.ResetInputEvent, handler);
    }

    public static void RemoveResetInputHandler(DependencyObject d, RoutedEventHandler handler)
    {
        UIElement uie = d as UIElement;
        if (uie == null)
        {
            return;
        }
        uie.RemoveHandler(ResetInputEventClass.ResetInputEvent, handler);
    }

玩得开心,希望能帮到你。

你也可以通过Commands

于 2013-02-28T14:47:20.810 回答