У меня есть 3 ViewModel
: базовая, и 2 дочерних. Хочу при помощи ViewModelLocator
иметь возможность управлять свойством, которое находится в базовой ВМ, из дочерних, так чтобы они работали с одним и тем же экземпляром, а не каждый со своим, и соответственно обе реагировали на изменения. Конкретно в базовой ВМ есть bool свойство, которое должно меняться из других ВМ.
Пользовался этой статьей(https://msdn.microsoft.com/en-us/library/hh821028.aspx). Создал в App.xaml
экземпляр ViewModelLocator
, сам класс должен отдавать экземпляр нужной ВМ, когда я делаю на него Binding
на Xaml
.
UPD
Locator
public class ViewModelLocator
{
private BaseViewModel baseVm;
public BaseViewModel BaseVm
{
get { return new BaseViewModel(); }
}
}
App.xaml
<viewModels:ViewModelLocator x:Key="ViewModelLocator"/>
MainPage.xaml
элементы которые забиндены на нужные мне св-ва из BaseViewModel
<Image Visibility="{Binding IsFilterImgVisible, Source={StaticResource ViewModelLocator} ,Converter={StaticResource BooleanToVisibilityConverter}}"/>
<controls:ImageManipulatorControl
Visibility="{Binding IsUserControlVisibile, Converter={StaticResource BooleanToVisibilityConverter}}">
</controls:ImageManipulatorControl>
C контролом вообще отдельная беда, при такой записи, что-то прозрачное накладывается на часть экрана(подозреваю что это контрол, хотя bool
изначально стоит false
)
В базовой VM лежат bool
свойства, которые меняются из дочерних VM применяя слово this.
, но результата никакого
Для решения проблемы создал Singleton
класс в котором разместил все нужные свойства. Для обращения к ним использовал
MySingletonClass.InstanceProperty.PropertyToChange=/*value*/
при Binding
необходимо тоже добавлять Instance
, для того чтобы ссылаться на существующий экземпляр класса и соответсвенно свойства
"{Binding Instance.IsFilterImgVisible , Source={StaticResource EditModeSwitcher}"
Ох, это же UWP, там всё странно.
Я не нашёл метод «из коробки», как сделать так, чтобы View не знало о VM. Но это можно симулировать. Не знаю, насколько мой метод хорош, у меня мало опыта с UWP.
Итак, что мы делаем.
Для начала, главную VM и подчинённые VM создаём в классе App
:
sealed partial class App : Application
{
MainVM mainVM;
public App()
{
SetupVM();
// стандартный код, сгенерированный шаблоном:
this.InitializeComponent();
this.Suspending += OnSuspending;
}
void SetupVM()
{
mainVM = new MainVM();
var partVM = new PartVM(mainVM);
var anotherPartVM = new AnotherPartVM(mainVM);
mainVM.Part = partVM;
mainVM.AnotherPart = anotherPartVM;
}
Далее, поскольку навигация идёт лишь через Frame.Navigate
, в котором невозможно указать экземпляр, а только тип (почему??), я передаю VM как параметр, чтобы окно само себе установило его в качестве VM:
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
// тут много сгенерированного кода
if (rootFrame.Content == null)
{
// здесь добавил mainVM вместо параметра
rootFrame.Navigate(typeof(MainPage), mainVM);
}
// Ensure the current window is active
Window.Current.Activate();
}
Теперь в коде страницы:
public sealed partial class MainPage : Page
{
public MainPage()
{
InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
// вытаскиваем DataContext из параметров навигации
DataContext = e.Parameter;
}
void OnNextClick(object sender, RoutedEventArgs e)
{
// при навигации в другое окно передаём ему DataContext
Frame.Navigate(typeof(NextPage), DataContext);
// это новое окно тоже должно будет вытащить его из параметра, как и это
}
}
Теперь, вложенный UserControl
. Ему нужно передать правильный DataContext
:
<local:InnerControl DataContext="{Binding Part}"/>
Наконец, при каком-нибудь действии внутри UserControl'а получает управление его VM, которая имеет у себя ссылку на MainVM
.
Всё!
Зачем делать свой велосипед, если можно воспользоваться готовым? Prism
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Добрый день! Как через C# CryptoApi вставить в подпись штамп времени, полученный от службы штампов времени (http://cryptoproru/tsp/tsp
Добрый день, господа! Есть необходимость вызвать дочерний action метод через @HtmlAction() (речь идет об ASP
Подскажите, пожалуйста, какой компонент в виде таблицы можно использовать в C# Windows Forms для ввода/вывода матрицы? (Что-то вроде StringGrid'а в Delphi)
Есть обратная связь, пользователь должен заполнить обязательное поле EmailПри нажатии на кнопку отправить, письмо отправляется на support@домен