如何使用RoutedEventArgs传递变量?

14
我有以下的类,想要将text变量作为RoutedEventArgs传递。
  public class CloseableTabItem : TabItem
  {
    String text;

    public CloseableTabItem()
    {
      //This style is defined in themes\generic.xaml
      DefaultStyleKeyProperty.OverrideMetadata(typeof(CloseableTabItem),
          new FrameworkPropertyMetadata(typeof(CloseableTabItem)));
    }

    public CloseableTabItem(String incomingText)
    {
      //This style is defined in themes\generic.xaml
      DefaultStyleKeyProperty.OverrideMetadata(typeof(CloseableTabItem),
          new FrameworkPropertyMetadata(typeof(CloseableTabItem)));
      text = incomingText;
    }

    public static readonly RoutedEvent CloseTabEvent =
        EventManager.RegisterRoutedEvent("CloseTab", RoutingStrategy.Bubble,
            typeof(RoutedEventHandler), typeof(CloseableTabItem));

    public event RoutedEventHandler CloseTab
    {
      add { AddHandler(CloseTabEvent, value); }
      remove { RemoveHandler(CloseTabEvent, value); }
    }

    public override void OnApplyTemplate()
    {
      base.OnApplyTemplate();

      Button closeButton = base.GetTemplateChild("PART_Close") as Button;
      if (closeButton != null)
        closeButton.Click += new System.Windows.RoutedEventHandler(closeButton_Click);
    }

    void closeButton_Click(object sender, System.Windows.RoutedEventArgs e)
    {
      this.RaiseEvent(new RoutedEventArgs(CloseTabEvent, this));
    }
  }

这是来自 Window1 的代码,它是一个 WPF 应用程序中的主类。

  public partial class Window1 : Window
  {
    public static Window1 myWindow1;

    public Window1()
    {
      myWindow1 = this;
      InitializeComponent();
      this.AddHandler(CloseableTabItem.CloseTabEvent, new RoutedEventHandler(this.CloseTab));
    }

    private void CloseTab(object source, RoutedEventArgs args)
    {
      TabItem tabItem = args.Source as TabItem;
      if (tabItem != null)
      {
        TabControl tabControl = tabItem.Parent as TabControl;
        if (tabControl != null)
          tabControl.Items.Remove(tabItem);
      }
    }

    private void btnAdd_Click(object sender, RoutedEventArgs e)
    {
      CloseableTabItem tabItem = new CloseableTabItem("THIS IS A TEST");
      MainTab.Items.Add(tabItem);
    }
  }

我希望能够在CloseTab方法中打印出"String text"的值。如何使"String text"能够通过RoutedEventArgs args传递?

最好的问候!

编辑

我对项目进行了一些更改,下面是代码:

ClosableTabItem.cs

namespace SampleTabControl
{
  public class CloseableTabItem : TabItem
  {

    String text;
    public delegate void TabsEventHandler(object sender, TabsEventArgs e);

    public CloseableTabItem()
    {
      //This style is defined in themes\generic.xaml
      DefaultStyleKeyProperty.OverrideMetadata(typeof(CloseableTabItem),
          new FrameworkPropertyMetadata(typeof(CloseableTabItem)));
    }

    public CloseableTabItem(String incomingText)
    {
      //This style is defined in themes\generic.xaml
      DefaultStyleKeyProperty.OverrideMetadata(typeof(CloseableTabItem),
          new FrameworkPropertyMetadata(typeof(CloseableTabItem)));
      this.text = incomingText;
    }

    public static readonly RoutedEvent CloseTabsEvent = EventManager.RegisterRoutedEvent("CloseTab", RoutingStrategy.Bubble, typeof(TabsEventHandler), typeof(CloseableTabItem));    

    public event TabsEventHandler CloseTab
    {
      add { AddHandler(CloseTabsEvent, value); }
      remove { RemoveHandler(CloseTabsEvent, value); }
    }


    public override void OnApplyTemplate()
    {
      base.OnApplyTemplate();

      Button closeButton = base.GetTemplateChild("PART_Close") as Button;
      if (closeButton != null)
        closeButton.Click += new System.Windows.RoutedEventHandler(closeButton_Click);
    }

    void closeButton_Click(object sender, System.Windows.RoutedEventArgs e)
    {
      TabsEventArgs args = new TabsEventArgs(CloseTabsEvent, text);
      RaiseEvent(args);
    }
  }
}

TabsEventArgs.cs

public class TabsEventArgs : RoutedEventArgs
{
    private readonly string text;

    public string Text
    {
        get { return text; }
    }

    public TabsEventArgs(RoutedEvent routedEvent, string text) : base(routedEvent)
    {
        this.text = text;
    }
}

Window1.cs

  public partial class Window1 : Window
  {
    public static Window1 myWindow1;

    public Window1()
    {
      myWindow1 = this;
      InitializeComponent();
      this.AddHandler(CloseableTabItem.CloseTabsEvent, new RoutedEventHandler(this.CloseTab));
    }

    private void CloseTab(object source, RoutedEventArgs args)
    {      
      TabItem tabItem = args.Source as TabItem;
      if (tabItem != null)
      {
        TabControl tabControl = tabItem.Parent as TabControl;
        if (tabControl != null)
          tabControl.Items.Remove(tabItem);
      }
    }

    private void btnAdd_Click(object sender, RoutedEventArgs e)
    {
      CloseableTabItem tabItem = new CloseableTabItem("THIS IS A TEST");
      MainTab.Items.Add(tabItem);
    }
  }
在进行更改后(当我打开超过1个选项卡时,应用程序会崩溃),您如何在Window1类的CloseTab方法中访问“string text”?

1
谢谢,我非常感激这个问题以及你所做的修改/补充。 - wonea
3个回答

16

我需要类似的东西,通过@Arya和@H.B.的帮助,我得到了这个:

我的自定义RoutedEventArgs子类

public class ChangePageEventArgs : RoutedEventArgs {
    private readonly int _pageNumber;

    public int PageNumber {
        get { return _pageNumber; }
    }

    public ChangePageEventArgs(RoutedEvent routedEvent, int pageNumber) : base(routedEvent) {
        this._pageNumber = pageNumber;
    }
}

我的子类

private void defineButton_Click(object sender, RoutedEventArgs e) {
    ChangePageItemList(2);
}

public static readonly RoutedEvent GoToItemPropertiesViewEvent = EventManager.RegisterRoutedEvent(
"GoToItemPropertiesView", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(NoObjectView));

// Provide CLR accessors for the event
public event RoutedEventHandler GoToItemPropertiesView {
    add { AddHandler(GoToItemPropertiesViewEvent, value); }
    remove { RemoveHandler(GoToItemPropertiesViewEvent, value); }
}

public void ChangePageItemList(int _pageNumber) {
    ChangePageEventArgs args = new ChangePageEventArgs(GoToItemPropertiesViewEvent, _pageNumber);
    this.RaiseEvent(args);
}

我的父类

private ItemListView createItemListView() {
    _itemListView = new ItemListView();
    _itemListView.GoToItemPropertiesView += new RoutedEventHandler(ChangePage);

    return _itemListView;
}

private void ChangePage(object sender, RoutedEventArgs e) {
    ChangePageEventArgs args = (ChangePageEventArgs)e;
    // Value of page number is 2
    int _pageNumber = args.PageNumber;
}
希望这能帮到你 @Arya

14

创建一个RoutedEventArgs的新子类,添加一个属性,在这个属性中可以存储要传递的变量,并创建一个相应的处理程序委托类型void(object,YourNewEventArgs),然后将其分配为您事件的处理程序类型的代理(目前使用普通的RoutedEventHandler,因此仅提供普通的RoutedEventArgs)。

如果要引发事件,您需要创建您的新事件args,并将变量传递到它的属性中。如何在处理程序中获取该值应该是不言自明的。


@Arya:你的CloseTabs方法仍然使用了通用的RoutedEventArgs,而应该使用TabsEventArgs,然后可以通过args.Text获取文本。我不知道为什么会崩溃,如果你想要帮助,请发布异常消息和堆栈跟踪。 - H.B.

0

1 - 创建一个新的事件数据类:

public class SelectedRowEventArgs : RoutedEventArgs
{
    public int Value { get; set; }

    public SelectedRowEventArgs(RoutedEvent routedEvent, int value) : base(routedEvent)
    {
        this.Value = value;
    }
}

2- 在用户控件中创建链接代码:

public partial class AusenciasBaseAdmin : UserControl
{

    public static readonly RoutedEvent RowChangedEvent = EventManager.RegisterRoutedEvent("RowChanged", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(AusenciasBaseAdmin));

    public event RoutedEventHandler RowChanged
    {
        add { AddHandler(RowChangedEvent, value); } remove { RemoveHandler(RowChangedEvent, value); }
    }



    public AusenciasBaseAdmin()
    {
        InitializeComponent();
    }


    private void RegAusencias_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        this.RaiseEvent(new SelectedRowEventArgs(RowChangedEvent, 1));
    }
}

3 - 在主窗体中链接用户控件:

<control:AusenciasBaseAdmin Grid.Row="0" Grid.Column="0"
                        x:Name="GridAusencias" 
                        RowChanged="GridAusencias_RowChanged_1"
                        />

4 - 主表单中的代码后面:

    private void GridAusencias_RowChanged_1(object sender, RoutedEventArgs e)
    {
        SelectedRowEventArgs t = (SelectedRowEventArgs)e;

        MessageBox.Show(t.Value.ToString());
    }

祝贺WPF团队。你们成功地完成了极其复杂的任务。


如果你想在MVVM模式下监听事件,那么监听事件会更加复杂。 - Etienne Charland

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接