【问题标题】:Static function as eventhandler in xaml静态函数作为 xaml 中的事件处理程序
【发布时间】:2011-11-10 09:42:40
【问题描述】:

我正在使用this 代码来模拟我的silverlight 应用程序中的选项卡功能。

我真的很想避免多次编写该函数,因为它必须在整个应用程序中的大量文本框中使用。我创建了一个静态类

public static class TabInsert
{
    private const string Tab = "    ";
    public static void textBox_KeyDown(object sender, KeyEventArgs e)
    {
        TextBox textBox = sender as TextBox;
        if (e.Key == Key.Tab)
        {
            int selectionStart = textBox.SelectionStart;
            textBox.Text = String.Format("{0}{1}{2}",
                    textBox.Text.Substring(0, textBox.SelectionStart),
                    Tab,
                    textBox.Text.Substring(textBox.SelectionStart + textBox.SelectionLength, (textBox.Text.Length) - (textBox.SelectionStart + textBox.SelectionLength))
                    );
            e.Handled = true;
            textBox.SelectionStart = selectionStart + Tab.Length;
        }
    } 
}

这样我就可以从各个地方访问它,就像textBox.KeyDown += TabInsert.textBox_KeyDown;

有没有办法在 XAML 中做到这一点?

【问题讨论】:

    标签: c# xaml silverlight-4.0 event-handling


    【解决方案1】:

    很遗憾,there is no direct way to do this in XAML。你在后面代码中编写的事件处理程序必须是实例方法,不能是静态方法。这些方法必须由 x:Class 标识的 CLR 命名空间内的分部类定义。您不能限定事件处理程序的名称来指示 XAML 处理器在不同的类范围内查找事件处理程序以进行事件连接。

    【讨论】:

      【解决方案2】:

      您可以创建一个行为(System.Windows.Interactivity 命名空间)以轻松附加到在 OnAttached() 覆盖中订阅事件的文本框,并像您一样进行处理并在 OnDetaching() 中取消订阅。

      类似:

      public class TabInsertBehavior : Behavior<TextBox>
      {
          /// <summary>
          /// Called after the behavior is attached to an AssociatedObject.
          /// </summary>
          /// <remarks>
          /// Override this to hook up functionality to the AssociatedObject.
          /// </remarks>
          protected override void OnAttached()
          {
              base.OnAttached();
              this.AssociatedObject.KeyDown += textBox_KeyDown;
          }
      
          private const string Tab = "    ";
          public static void textBox_KeyDown(object sender, KeyEventArgs e)
          {
              TextBox textBox = sender as TextBox;
              if (e.Key == Key.Tab)
              {
                  int selectionStart = textBox.SelectionStart;
                  textBox.Text = String.Format("{0}{1}{2}",
                          textBox.Text.Substring(0, textBox.SelectionStart),
                          Tab,
                          textBox.Text.Substring(textBox.SelectionStart + textBox.SelectionLength, (textBox.Text.Length) - (textBox.SelectionStart + textBox.SelectionLength))
                          );
                  e.Handled = true;
                  textBox.SelectionStart = selectionStart + Tab.Length;
              }
          } 
      
          /// <summary>
          /// Called when the behavior is being detached from its AssociatedObject, but before it has actually occurred.
          /// </summary>
          /// <remarks>
          /// Override this to unhook functionality from the AssociatedObject.
          /// </remarks>
          protected override void OnDetaching()
          {
              base.OnDetaching();
              this.AssociatedObject.KeyDown -= textBox_KeyDown;
          }
      }
      

      【讨论】:

      • 在你的 xaml 中你会做
      • 我对 xyzzer 非常不满——附加的行为是一个很好的解决方法。 (另见How to attach behavior in code behind
      • 我也同意,但这只会构建一个非常讨厌的 XAML,而且我最不想拥有它,因为有很多文本框需要这个功能......
      • 您可以注册一个附加的依赖属性,它与行为做同样的事情。由于您提到的确切原因,它实际上会更好。只需定义一个类似 TextBoxExtensions 的类,执行类似 DependencyProperty.RegisterAttached("AutoTabs", typeof(bool), typeof(TextBoxExtensions), new PropertyMetadata(null, OnAutoTabsChanged));然后在 OnAutoTabsChanged 中,当它设置为 true 时 - 订阅您的事件,当它设置为 false 时 - 取消订阅。然后,您将使用它作为属性,例如
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多