Contentcontrol не може да се актуализира, когато свойството на съдържанието се промени от извикване в рамките на заредения потребителски контрол

Имам 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. Добавете този бутон към вашия потребителски контрол1 в примера, който ми дадохте

        <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 "); } } Трябва ли да правя още ръчна актуализация на GUI от ViewModel или това е достатъчно? - person Swift; 26.03.2013
comment
мисля, че трябва да видя повече код, как се дефинира свойството за активен контрол? Можете ли да покажете как е дефиниран вашият контекст на данни в основния изглед? - person J King; 26.03.2013
comment
Здравей J King, съставих малък пример за теб, за да можеш да видиш как постъпих: връзка - person Swift; 27.03.2013
comment
страхотно, вижте моята редакция, която има бутон, работещ с ICommand от usercontrol - person J King; 27.03.2013
comment
Ти си моят герой, благодаря ти много! Сега просто трябва да разбера как да направя същото (да намеря прозореца), когато хоствам contentcontrol в TabControl-Tab и искам да добавя раздел отвътре, но предполагам, че това е същото мислене (но сега предшественикът е TabControl вместо Window, така че трябва да отида едно ниво нагоре). - person Swift; 28.03.2013
comment
Ако имате само един прозорец, това винаги ще работи, независимо колко вложени са вашите контроли. Използвал съм го в мрежа от данни, в мрежа, в разширител, в друга мрежа, в контрола на съдържанието, в потребителска контрола, в прозорец. Той търси целия път нагоре във визуалното дърво, за да намери тип прозорец. - person J King; 28.03.2013