Мне нужно использовать некоторые функции, включенные в стороннюю сборку (DevExpress), перед тем, как я использую ее в своем основном приложении WPF. Я пытался использовать его с помощью Reflection и внешнего псевдонима, чтобы избежать конфликта между классами, событиями (и т. Д.), Имеющими одинаковое имя между двумя сборками.
Поскольку у меня возникли проблемы с использованием этих решений, в конце концов я решил создать оболочку, внешнюю по отношению к моему основному проекту, имеющую в своих ссылках "старую" сборку, и объявив классы, которые мне нужно просто наследовать от классов сборки.
Казалось, что это решение работает правильно, но я столкнулся с большой проблемой, связанной с обработкой событий.
Мне нужно обработать событие, определенное в обеих сборках, поэтому я попытался следовать тому же пути, который описал ранее.
В моем приложении-оболочке:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DevExpress.Xpf.Printing;
namespace WrapperSimpleLink101
{
//declaration of my event
public delegate void EventHandlerNew<ClassEvento>(object obj, ClassEvento ClEv);
//declaration of a working class
public class Class1 : DevExpress.Xpf.Printing.SimpleLink
{
public ColumnDirection vDirezione;
public Class1(ColumnDirection direzione)
{
vDirezione = direzione;
}
public ColumnDirection direzione
{
get { return vDirezione; }
set { vDirezione = value; }
}
//event raising DelegateCasting
public void SetCreateDetail(EventHandlerNew<ClassEvento> pD)
{
this.CreateDetail += DelegateUtility.Cast<EventHandler<CreateAreaEventArgs>>(pD);
}
}
//my event
public class ClassEvento : DevExpress.Xpf.Printing.CreateAreaEventArgs
{
public ClassEvento(int detailindex): base(detailindex)
{
this.detailIndex = detailindex;
}
public int detailIndex { get; set; }
}
//utility to cast eventhandlernew<ClassEvento> to EventHandler<CreateAreaEventArgs>
public static class DelegateUtility
{
public static T Cast<T>(Delegate source) where T : class
{
return Cast(source, typeof(T)) as T;
}
public static Delegate Cast(Delegate source, Type type)
{
if (source == null)
return null;
Delegate[] delegates = source.GetInvocationList();
if (delegates.Length == 1)
// the line where it's raised error ArgumentException: Error binding to target method
**return Delegate.CreateDelegate(type, delegates[0].Target, delegates[0].Method);**
Delegate[] delegatesDest = new Delegate[delegates.Length];
for (int nDelegate = 0; nDelegate < delegates.Length; nDelegate++)
delegatesDest[nDelegate] = Delegate.CreateDelegate(type,
delegates[nDelegate].Target, delegates[nDelegate].Method);
return Delegate.Combine(delegatesDest);
}
}
}
В основном приложении WPF:
using WrapperSimpleLink101;
[...]
Class1 slink = new Class1(ColumnDirection.AcrossThenDown);
[...]
//invocation of eventhandlernew
slink.SetCreateDetail(new EventHandlerNew<ClassEvento>(slink_CreateDetail));
[...]
public void slink_CreateDetail(object sender, ClassEvento e)
{
e.Data = this.scoreCards[e.DetailIndex];
}
Мне нужно использовать делегаты приведения для обработки этого события, потому что я не могу напрямую (в основном приложении) передать slink.CreateDetail моего ClassEvento (вместо CreateAreaEventArgs), даже если ClassEvento наследует от CreateAreaEventArgs (и я мог бы также указать причину) но у меня есть ошибка, показанная ранее.
Осуществляя более глубокую отладку, я заметил, что EventHandler, переданный моей внешней оболочке, вызвал исключение в типе System.InvalidOperationException, точно «Метод может вызываться только для типа, для которого Type.IsGenericParameter имеет значение true», но я не уверен что основная ошибка и эта связаны.
Я пытался решить сам и через MSDN / Internet, но без удачи, поэтому я пишу здесь, чтобы попросить помощи сообщества.
Если у вас есть предложения, они будут очень благодарны.
Если что-то не понятно, пожалуйста, спросите меня дополнительную информацию.
Заранее спасибо за ответы.
Нино