2013-02-28 86 views
0

我对这个问题进行了搜索,但无法收集任何信息,我想知道是否有可能附加的行为来处理附加事件?在WPF中处理附加事件的附加行为

我已经在类中声明了一个事件,并附加了一个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); 
} 

回答

2

当然这是可能的。让我看看你的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"; 
    } 

因为您设置了TextBox Name属性和Button你可以从后面的代码在你的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> 

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

我必须设置行为上True因为默认值是false,当值不等于旧,则属性格式改变的情况下将我的自定义逻辑调用是这样的:

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

内部属性改变了事件,我将其称为到true。当应用程序处于后台时,我会通过告诉调度程序执行我的代码来等待所有内容。然后我找到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

+0

我添加了代码并进行了描述。 – Harsha 2013-02-28 17:34:48

+0

您的完整xaml缺失,我没有看到按钮,它在哪里? – 2013-02-28 19:30:42

+0

和void OnAttached()来自哪里?请妥善发布一些代码。 – 2013-02-28 19:41:25

3

你的问题很简单。文本框注册了该事件,但文本框的父级正在提高它。因此处理程序从不被调用。您可以更改事件以使其成为Tunneling事件而不是Bubbling。或者你可以在你的文本框中获得一个句柄(在后面的代码中给它一个名字和引用)。并让它提高事件。然后

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

,并应解决您的问题。

+2

+ 1反击一个没有任何文字的巨魔。 – code4life 2014-03-27 16:23:08