#c# #action
#c# #Экшен
Вопрос:
Я пытаюсь вызвать несколько методов с разными параметрами. Например, у меня есть UIElement, который я хочу переместить и удалить. В своем классе я реализую эти методы:
public void Move(params object[] args)
{
Point lastpoint = (Point)Convert.ChangeType(args[0], typeof(Point));
Point newpoint = (Point)Convert.ChangeType(args[1], typeof(Point));
double left = Canvas.GetLeft(this) (newpoint.X - lastpoint.X);
double top = Canvas.GetTop(this) (newpoint.Y - lastpoint.Y);
Canvas.SetLeft(this, left);
Canvas.SetTop(this, top);
}
public void Remove(params object[] args)
{
Canvas parent = this.Parent as Canvas;
parent.Children.Remove(this);
}
где:
- аргументы в Move состоят из двух точек
- аргументы в Remove должны быть нулевыми
Я использую класс для сбора всех моих событий из разных источников (мышь, касание, прыжок …), который называется EventLinker . Это довольно просто, поскольку оно просто содержит перечисление:
public enum GestureKey
{
OnClick,
OnDoubleClick,
OnLongClick,
OnRightClick,
OnDoubleRightClick,
OnLongRightClick,
OnMove
};
Которые я могу использовать в словаре:
private Dictionary<GestureKey, Action<object[]>> MyDictionary;
Методы Переместить и Удалить связаны двумя разными жестами:
MyDictionary.Add(GestureKey.OnRightClick, Remove);
MyDictionary.Add(GestureKey.OnMove, Move);
Идея состоит в том, чтобы использовать этот словарь в нескольких прослушивателях, подключенных к одному и тому же UIElement, чтобы иметь возможность использовать мышь, сенсорный экран, LeapMotion … для управления моим приложением. Чтобы привести пример, когда я обнаруживаю щелчок в моем прослушивателе для моей мыши, я вызываю метод OnClick в моем словаре:
if (MyDictionary.ContainsKey(GestureKey.OnClick))
{
object[] args = { _lastPoint };
Application.Current.Dispatcher.BeginInvoke(MyDictionary[GestureKey.OnClick], args);
}
Это не должно быть проблемой, если все мои методы будут содержать одинаковый номер и тип параметров, но здесь у меня проблема с преобразованием, но это решение не очень чистое, и я уверен, что есть способ сделать это так, как мне хотелось бы.
Я хочу вызывать свои методы одинаково, даже если у них другой прототип. Если кто-нибудь знает, как это сделать, дайте мне знать!
РЕДАКТИРОВАТЬ: я думаю, проблема в словаре, который я использую, чтобы связать свои методы с моим перечислением. Он должен содержать методы с одинаковым прототипом. Есть ли какой-либо класс, который я мог бы использовать, который мог бы делать то же самое без той же проблемы с прототипом?
EDIT2: В идеале я должен иметь
public void Move(Point lastpoint, Point newpoint)
{
double left = Canvas.GetLeft(this) (newpoint.X - lastpoint.X);
double top = Canvas.GetTop(this) (newpoint.Y - lastpoint.Y);
Canvas.SetLeft(this, left);
Canvas.SetTop(this, top);
}
public void Remove()
{
Canvas parent = this.Parent as Canvas;
parent.Children.Remove(this);
}
Я думаю, проблема заключается в словаре, который я использую для привязки своих методов к GestureKey (см. Выше).
private Dictionary<GestureKey, Action<object[]>> MyDictionary;
Класс dictionary позволяет мне связывать перечисление с любым типом, здесь Действие. Однако я должен указать, какие параметры принимает мое действие, что для меня является динамическим значением. Я думаю, я должен сделать что-то вроде:
private Dictionary<GestureKey, Action<TYPELIST>> MyDictionary;
Но я не знаю, как это сделать. Я пытался использовать список, но у меня та же проблема, он запрашивает у меня что-то статическое. СПИСОК типов должен быть проинформирован динамически. И я не знаю, подходит ли для этого класс Dictionary, может быть, для этого есть лучший класс.
Комментарии:
1. это все еще трудно понять. можете ли вы добавить какой-нибудь пример псевдокода того, что вы пытаетесь сделать? я согласен, что, вероятно, есть решение, как только вы его описали.
2. Вы хотите, чтобы сигнатура move была Move(Point old, Point new) и Remove() ? Это то, что ты пытаешься сказать?
3. я вижу, что вы пытаетесь там сделать. я посмотрю на это. некоторое время назад я тоже пытался делать подобные вещи
4. Спасибо. Я дам вам знать, если что-то найду.
Ответ №1:
Здесь немного другая разметка, но вы поймете это в любом случае. Для меня работает следующее:
Dictionary<string, Delegate> _callbacks = new Dictionary<string, Delegate>();
public MainWindow()
{
InitializeComponent();
_callbacks.Add("move", new Action<Point, Point>(Move));
_callbacks.Add("remove", new Action(Remove));
Application.Current.Dispatcher.BeginInvoke(_callbacks["move"], new Point(5, 6), new Point(1, 3));
Application.Current.Dispatcher.BeginInvoke(_callbacks["remove"]);
}
public void Move(Point something1, Point something2)
{
}
public void Remove()
{
}
Комментарии:
1. Пожалуйста. Как ни странно, когда мне было любопытно, я не мог закончить это. ха-ха. Ну что ж, видимо, мой мозг тем временем провел дополнительные исследования. Рад, что смог помочь
2. Лучше так, чем иначе ^^