سؤال

I have an problem with this three classes.

In first class i'm extending for listview class for common method

In second class we put one method it's invoke by the 1st class

This is fine for above two classes but in my third class need to pass that T, M values. But i don't understand how to do this?

anybody help this issue?

Thank you

1st Class

public class MyListView : ListView
{
    public UserControl uc { get; set; }
    internal MyLEvent<Type,Type> MyLEvnt  { get; set; }
    public MyListView()
    {
        PreviewKeyDown += new KeyEventHandler(MyListView_PreviewKeyDown);
    }
    private void MyListView_PreviewKeyDown(object sender,KeyEventArgs e)
    {
         ListView view = sender as ListView;
         var item = view.SelectedItem;
        if (item != null)
        {
            string str = item.GetType().Name;
            if (e.Key == Key.Delete)
            {
                MyLEvnt.Method(item, "Delete");
            }
            else if (e.Key == Key.Enter)
            {
                MyLEvnt.Method(item, "Modify");
                uc.GetType().GetProperty("Update").SetValue(uc, 1, null);
                MethodInfo mi = uc.GetType().GetMethod("IClear");
                mi.Invoke(uc, null);
            }
        }
    }
}

2nd Class

 public class MyLEvent<T,M> where T : class where M : class
{
    private M manager;
    private T type;
    public MyLEvent()
    {

    }
    public object Method(object _view, string flog)
    {
        object retVal = null;
        type = Activator.CreateInstance<T>();
        manager = Activator.CreateInstance<M>();
        if (flog == "Modify")
        {
            MethodInfo method = typeof(M).GetMethod("getData");
            type = (T)method.Invoke(manager, new[] { _view });

        }
        else if (flog == "Set")
        {
            MethodInfo method = typeof(M).GetMethod("setDefault");
            retVal = method.Invoke(manager, new[] { _view });
        }
        else
        {
            if (MyMessage.askDelete() == true)
            {
                PropertyClass.Properties(_view, type, 'U');
                MethodInfo method = typeof(M).GetMethod("Delete");
                 retVal = method.Invoke(manager, new[] { type });
            }
        }
        return retVal;
    }
}

3rd Class

 public partial class SubASettings : UserControl
{
     public SubASettings()
    {
        InitializeComponent();
        MAILV.uc = this;
        MAILV.MyLEvnt = new MyLEvent<typeof(InvMail), MailManager>();
        Clear();
    }
}

Thank you,

هل كانت مفيدة؟

المحلول

You can add a constraint to your generic type by declaring an interface:

public interface IManager 
{
    void getData();
    setDefault
    Delete
}

Define this constraint in declaration of second class which means that M type should implement IManager interface:

public class MyLEvent<T, M>
    where T : class
    where M : class, IManager

Then, you can invoke members of your class which defined in the interface:

public class MyLEvent<T, M>
    where T : class
    where M : class, IManager
{
    private M manager;

    public MyLEvent()
    {
        manager.Delete();
    }
}

نصائح أخرى

The declaration:

public class MyLEvent<T,M> where T : class where M : class
{
...
}

...defines a generic type that is used to create concrete types when provided with the appropriate type parameters. You cannot use generic types directly, you can only use them to create concrete types which can then be used.

For example, the List<T> generic type defines structure and code that can be used to create a variety of concrete types depending on the type parameter you use. List<string> is a concrete type created from the List<T> generic type.

In the case of your MyLEvent generic, there are two type parameters: T and M. You need to specify both of those to create a concrete type that can be used.

In your MyListView class you define the MyLEvnt field like this:

internal MyLEvent<Type,Type> MyLEvnt  { get; set; }

This defines the MyLEvnt field as an instance of the concrete type MyLEvent<Type, Type>. Note that Type is a class that is used to access information about types. In this usage it is not a way to avoid supplying a type parameter, it is a type parameter.

In your third class you then do this:

MAILV.MyLEvnt = new MyLEvent<typeof(InvMail), MailManager>();

Even when we take the typeof() out of it, this will fail because you are attempting to assign an instance of MyLEvent<InvMail, MailManager> to a field of type MyLEvent<Type, Type>. These are different types, just as List<string> is different from List<int>.

You need to read the MSDN articles on Generics. These explain the details of how generics work and give you a lot of examples of how to use them and why.

Thank you so much for supporting. And i got one solution for this....

This is my previous 1st class

public class MyListView : ListView
{
  public UserControl uc { get; set; }
  internal MyLEvent<Type,Type> MyLEvnt  { get; set; }
  public MyListView()
  {
    PreviewKeyDown += new KeyEventHandler(MyListView_PreviewKeyDown);
  }
  private void MyListView_PreviewKeyDown(object sender,KeyEventArgs e)
  {
     ListView view = sender as ListView;
     var item = view.SelectedItem;
    if (item != null)
    {
        string str = item.GetType().Name;
        if (e.Key == Key.Delete)
        {
            MyLEvnt.Method(item, "Delete");
        }
        else if (e.Key == Key.Enter)
        {
            MyLEvnt.Method(item, "Modify");
            uc.GetType().GetProperty("Update").SetValue(uc, 1, null);
            MethodInfo mi = uc.GetType().GetMethod("IClear");
            mi.Invoke(uc, null);
        }
    }
 }

}

After modified in my level....

 public class MyListView : ListView
{
    public UserControl uc { get; set; }
    public object ML { get; set; }
    public MyListView()
    {
        PreviewKeyDown += new KeyEventHandler(MyListView_PreviewKeyDown);
    }
    public void Methode<T,M>() where T : class where M : class
    {
        ListViewEvents<T, M> mn = new ListViewEvents<T, M>();
        ML = mn;
    }
    private void MyListView_PreviewKeyDown(object sender,KeyEventArgs e)
    {
         ListView view = sender as ListView;
         var item = view.SelectedItem;
        if (item != null)
        {
            string str = item.GetType().Name;
            if (e.Key == Key.Delete)
            {
                MethodInfo mi = ML.GetType().GetMethod("Method");
                mi.Invoke(ML,new[]{item,"Delete"});
                MethodInfo m = uc.GetType().GetMethod("IClear");
                m.Invoke(uc, null);
            }
            else if (e.Key == Key.Enter)
            {
                MethodInfo m = ML.GetType().GetMethod("Method");
                object ob = m.Invoke(ML, new[] { item, "Modify" });
                PropertyClass.Properties(uc, ob, 'U');
            }
        }
    }
}

This solution is better working for me. But if is there any wrong with this please let me guide

Thank you again...

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top