Контент-контроль не может обновиться, когда свойство содержимого изменилось из-за вызова в загруженном пользовательском элементе управления

У меня есть MainView, который содержит один ContentControl, ContentControl загружает пользовательский элемент управления по умолчанию при загрузке приложения.

<ContentControl x:Name="MainContentArea" Content="{Binding ActiveControl}"/>

Загружаемый пользовательский элемент управления загружает несколько плагинов (не имеет значения) и при выборе элемента из поля со списком запускает ICommand, который существует в Parent (MainViewModel), используя концепцию MVVM Light для ViewModelLocator.

private void CreateSelectedPlugin(IExtendedUIViewFactory plugin)
    {
        var pluginStartControl = plugin.Create();
        _locator.Main.DefaultCommand.Execute(pluginStartControl);
    }

Проблема в том, что ContentControl не обновляется, я могу установить точку останова и увидеть, что команда выполняется в MainViewModel и что отправляемая мной переменная действительна.

public ICommand DefaultCommand { get; set; }
    public MainWindowViewModel()
    {
        DefaultCommand = new RelayCommand<object>(LoadSection, o => true);
    }

    private void LoadSection(object plugin)
    {
        ActiveControl = plugin;
        //does not matter if i set it to null here
    }

Вызов LoadSection или тестовой функции, которая просто устанавливает ContentControl в null, из MainView/MainViewModel, работает, как и ожидалось.

Какое удержание команды, которую я отправляю из элемента управления, имеет в Contentcontrol, из-за чего он не хочет загружать что-то еще?


person Swift    schedule 25.03.2013    source источник


Ответы (1)


вам нужно уведомить пользовательский интерфейс о том, что произошло изменение. Реализуйте INotifyPropertyChanged и добавьте его в назначение ActiveControl:

private void LoadSection(object plugin)
{
    ActiveControl = plugin;
    NotifyPropertyChanged();
}

Вот документация

ИЗМЕНИТЬ №1

Я думаю, вам следует использовать кнопку в пользовательском элементе управления для привязки к команде в главном окне. Это лучше, чем пытаться передать модель представления основного окна пользовательскому элементу управления, что создает зависимость и нарушает шаблон MVVM. Добавьте эту кнопку в свой usercontrol1 в образце, который вы мне дали.

        <Button Content="Set MyContent to null using binding to main window command" Height="40" Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}},Path=DataContext.PublicCommand}"></Button>

Он использует относительную привязку к команде в главном окне, которое в моем приложении я использую в одном главном окне для хранения всех пользовательских элементов управления/представлений. Таким образом, я могу контролировать то, что отображается, и использовать определения команд только в одном месте, которое, как я знаю, всегда будет доступно.

надеюсь это поможет

person J King    schedule 26.03.2013
comment
Привет, спасибо за ответ, на самом деле я реализовал в нем ModelViewBase, который является INotifyProperty, поэтому мой ActiveControl выглядит следующим образом: public object ActiveControl { get { return activeControl; } set { ActiveControl = value; RaisePropertyChanged("ActiveControl "); } } Нужно ли мне вручную обновлять графический интерфейс из ViewModel или этого достаточно? - person Swift; 26.03.2013
comment
я думаю, мне нужно увидеть больше кода, как определяется свойство активного элемента управления? Можете ли вы показать, как определяется ваш контекст данных mainview? - person J King; 26.03.2013
comment
Привет, Джей Кинг, я собрал для вас небольшой пример, чтобы вы могли увидеть, как я это сделал: ссылка - person Swift; 27.03.2013
comment
отлично, посмотрите мое редактирование, в котором есть кнопка, работающая с помощью ICommand из пользовательского контроля - person J King; 27.03.2013
comment
Ты мой герой, спасибо тебе большое! Теперь мне просто нужно выяснить, как сделать то же самое (найти окно), когда я размещаю элемент управления контентом внутри TabControl-Tab и хочу добавить вкладку изнутри, но я предполагаю, что это то же самое мышление (но теперь предком является TabControl вместо Window, поэтому мне нужно подняться на один уровень выше). - person Swift; 28.03.2013
comment
Если у вас есть только одно окно, это всегда будет работать, независимо от того, насколько вложенными являются ваши элементы управления. Я использовал его внутри сетки данных, внутри сетки, внутри расширителя, внутри другой сетки, внутри элемента управления содержимым, внутри пользовательского элемента управления, в окне. Он просматривает все визуальное дерево, чтобы найти тип окна. - person J King; 28.03.2013