关于这个问题我用Google搜索但是无法收集任何信息,我想知道附加行为是否有可能处理附加事件?
我在类中声明了一个事件,并且我附加到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);
}
}
这是我的Event类,这就是我在行为中处理它的方式
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);
}
答案 0 :(得分:3)
你的问题很简单。文本框已为事件注册,但文本框的父级正在提升它。因此从不调用处理程序。您可以更改事件以使其成为隧道事件而不是冒泡。或者你可以获得文本框的句柄(在后面的代码中给它一个名称和引用)。并举起活动。
<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);
}
这应该可以解决你的问题。
答案 1 :(得分: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
和Button
设置了Name属性,所以您可以从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
,当值不等于old时,将使用我的自定义逻辑调用propery changed事件:
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);
}
}
在我将false
更改为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