Передача переменной с помощью RoutedEventArgs?

#c# #wpf #routedeventargs

#c# #wpf #routedeventargs

Вопрос:

У меня есть следующий класс, и я хочу передать текстовую переменную как RoutedEventArgs.

   public class CloseableTabItem : TabItem
  {
    String text;

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

    public CloseableTabItem(String incomingText)
    {
      //This style is defined in themesgeneric.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);
    }
  }
  

Я хочу иметь возможность печатать значение «String text» в методе CloseTab. Как я могу передать «текст строки» с помощью аргументов RoutedEventArgs?

С наилучшими пожеланиями!

Редактировать

Я внес некоторые изменения в проект, и вот код

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 themesgeneric.xaml
      DefaultStyleKeyProperty.OverrideMetadata(typeof(CloseableTabItem),
          new FrameworkPropertyMetadata(typeof(CloseableTabItem)));
    }

    public CloseableTabItem(String incomingText)
    {
      //This style is defined in themesgeneric.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 вкладки, приложение вылетает), как бы вы получили доступ к «string text» в методе CloseTab в классе Window1?

Комментарии:

1. Спасибо, я действительно ценю этот вопрос и внесенные вами поправки / дополнения.

Ответ №1:

Мне нужно было что-то подобное, и с помощью @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

Ответ №2:

Создайте новый подкласс RoutedEventArgs , добавьте к нему свойство, в котором вы можете сохранить передаваемую переменную, и создайте соответствующий делегат обработчика типа void (object, YourNewEventArgs) , который вы затем назначаете в качестве типа обработчика вашего события (который в настоящее время использует обычный, RoutedEventHandler который, следовательно, обеспечивает только обычный RoutedEventArgs ).

Если затем должно быть вызвано событие, вам нужно создать свои новые аргументы события и передать переменную в ее свойство для этой переменной. Способ получения значения в обработчике должен быть понятен сам по себе.

Комментарии:

1. @Arya: Ваш CloseTabs метод по-прежнему использует универсальный, RoutedEventArgs когда он должен иметь TabsEventArgs , затем вы можете получить текст через args.Text . Я не знаю, почему это приведет к сбою, вы отправляете сообщение об исключении и трассировку стека, если вам нужна помощь с этим.

Ответ №3:

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. ВЫ ДОБИЛИСЬ ТОГО, ЧТО СДЕЛАЛИ ЭТО ЧРЕЗВЫЧАЙНО СЛОЖНЫМ

Комментарии:

1. Тогда, если вы хотите прослушать событие в шаблоне MVVM, это еще больше усложняет процесс прослушивания события.