WPF MVVM - mvvm light не отправляет и не регистрирует значения - PullRequest
0 голосов
/ 04 мая 2018

AssemblyHelper.cs

namespace TEST.Model.BaseClass
{
    public static class AssemblyHelper
    {
        public static IEnumerable<Type> GetLoadableTypes(Assembly assembly)
        {
            if (assembly == null) throw new ArgumentNullException(nameof(assembly));

            try
            {
                return assembly.GetTypes();
            }
            catch (ReflectionTypeLoadException e)
            {
                return e.Types.Where(t => t != null);
            }
        }

        public static Type GetTypeByClassName(Assembly assembly, string className)
        {
            if (assembly == null) throw new ArgumentNullException(nameof(assembly));

            return AssemblyHelper.GetLoadableTypes(assembly).Where(a => a.Name == className).FirstOrDefault();
        }
    }
}

MainWindowsViewModel.cs

namespace TEST.ViewModel
{
    public class MainWindowViewModel : BaseViewModel
    {
        private DatabaseEntity db;

        private ReadOnlyCollection<LeftNavigation> _LeftNavigation;
        private DispatcherTimer Timer;

                public Assembly Assembly
        {
            get
            {
                return Assembly.GetExecutingAssembly();
            }
        }

        public ReadOnlyCollection<LeftNavigation> LeftNavigation
        {
            get
            {
                if (_LeftNavigation == null)
                {
                    Messenger.Default.Register<string>(this, CheckMessage);
                    //MethodInfo methodInfo = AssemblyHelper.GetTypeByClassName(Assembly, "AddValueViewModel").GetMethod("CallMessenger");
                    //methodInfo.Invoke(AssemblyHelper.GetConstructorByClassName(Assembly, "AddValueViewModel"), null);

                    db = new DatabaseEntity();
                    IQueryable<LeftNavigation> ln = new LeftNavigation(db).GetLeftNavigation();
                    foreach (var o in ln)
                    {
                        o.Command = new BaseCommand(() => OpenOneTab(AssemblyHelper.GetTypeByClassName(Assembly, o.Reference)));
                    }
                    _LeftNavigation = new ReadOnlyCollection<LeftNavigation>(ln.ToList());
                }
                return _LeftNavigation;
            }
        }

        public MainWindowViewModel() {}

        private void CheckMessage(string msg)
        {
            if (msg.Contains(","))
            {
                List<string> msgList = new List<string>(msg.Split(new string[] { "," }, StringSplitOptions.None));
                //Type typeHelper = null;
                //string typeNameHelper = "";

                foreach (var m in msgList)
                {
                    Type type = AssemblyHelper.GetTypeByClassName(Assembly, m);
                    if (type != null)
                    {
                        base.OpenOneTab(AssemblyHelper.GetTypeByClassName(Assembly, m));
                        //typeHelper = type;
                        //typeNameHelper = m;
                        continue;
                    }

                    int value;
                    if (int.TryParse(m, out value))
                    {
                        //MethodInfo methodInfo = typeHelper.GetMethod("CallMessenger");
                        //if (methodInfo != null)
                        //{
                        //    methodInfo.Invoke(AssemblyHelper.GetConstructorByClassName(Assembly, typeNameHelper), null);
                            Messenger.Default.Send(value);
                        //}
                    }
                }
            } else
            {
                base.OpenOneTab(AssemblyHelper.GetTypeByClassName(Assembly, msg));
            }
        }
    }
}

В MainWindowVireModel.cs в CheckMessage я получаю «AddValueViewModel, 2» из CategoriesViewModel.cs, и здесь отправка и регистрация работают нормально. Сначала я открываю новую вкладку, а затем хочу отправить новое сообщение с «2» в AddValueViewModel.cs

AddValueViewModel.cs

namespace TEST.ViewModel.Tab
{
    public class AddValueViewModel : JedenViewModel<CategoryValue>
    {
        public AddValueViewModel()
             : base()
        {
            base.DisplayName = "Add Value";
            item = new CategoryValue();
            Messenger.Default.Register<string>(this, CheckMessage2);
        }

        private int _CategoryId;
        public int CategoryId
        {
            get
            {
                return _CategoryId;
            }
            set
            {
                if (_CategoryId != value)
                {
                    _CategoryId = value;
                    OnPropertyChanged(() => _CategoryId);
                }
            }
        }

        private void CheckMessage2(string msg)
        {
            if (msg.Contains(","))
            {
                int value;
                if (int.TryParse(msg, out value)) { CategoryId = value; };
            }
        }

        public override void Save()
        {
            item.CategoryId = CategoryId;
            db.KategoriaWartosc.Add(item);
            db.SaveChanges();
        }

        //public void CallMessenger()
        //{
        //    Messenger.Default.Register<string>(this, CheckMessage2);
        //}
        #endregion Helpers
    }
}

Метод открытой вкладки

public void OpenOneTab(Type tabType)
{
    dynamic workspace = Workspaces.FirstOrDefault(vm => vm.GetType() == tabType);
    if (workspace == null)
    {
        workspace = Activator.CreateInstance(tabType);
        Workspaces.Add(workspace);
    }
    SetActiveWorkspace(workspace);
}

Я перехожу к AddValueViewModel по кнопке с помощью команды из CategoriesViewModel. Когда вкладка AddValueViewModel открывается в первый раз - CheckMessage2 не запускается, но когда я закрываю вкладку и снова перехожу на AddValueViewModel, CheckMessage2 получает то же значение, что и в MainWindowsViewModel - «AddValueViewModel, 2»

Я пытался использовать 'Messenger.Default.Unregister (это, CheckMessage); 'и' Messenger.Reset (); ' прямо перед отправкой значения в MainWindowsViewModel, но оно не работает

В примерах есть закомментированный код, который должен был дать мне уверенность, что я сначала вызываю 'register', а затем 'send' (вызывайте метод по отражению)

MVVM light - это что-то новое для меня

Вопросы: Я не знаю, почему в первый раз я не могу получить значения в CheckMessage2. Во второй раз, если я получаю что-то, данные, которые я посылаю, не являются данными, которые я ожидал.

1 Ответ

0 голосов
/ 05 мая 2018

Тип сообщения, ожидаемого моделью представления, имеет тип string

Messenger.Default.Register<string>

Тип отправляемого сообщения типа int. Таким образом, модель представления не может получить сообщение.

...