WPF - Просмотр свойства обновления модели через фонового работника, но представление не обновляет некоторые элементы, пока не сфокусировано - PullRequest
3 голосов
/ 17 мая 2011

Просмотр модели загружает данные асинхронно с использованием фонового рабочего потока в модели.Все свойства в модели и модели представления вызывают события измененного свойства, и все свойства обновляются в представлении, как и ожидалось, за исключением кнопок 2, состояние которых IsEnabled зависит от результата некоторых загруженных свойств.

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

Есть какие-нибудь подсказки относительно того, как наилучшим образом решить эту проблему?Я использую mvvm-light framework, но это не должно иметь значения.

Я пытался привязать IsEnabled к кнопке, а не полагаться только на свойство Command, но это не имело значения.Через журнал я подтвердил, что свойства модели представления установлены, и для свойств, связанных с кнопками, вызывается событие PropertyChanged.

Рассматривается отправка сообщения с помощью программы mvvm-light messenger из модели представления впосмотреть на завершение асинхронного события и потом как-нибудь?запуск обновления представления, но это похоже на кучу.

Обновление

Благодаря ответу blindmeis я проверил поведение кнопки без набора привязки Command, то есть просто связывание свойства IsEnabled и егоработает как положено!

<Button 
    Grid.Column="2" Content="{Binding LoadProjectsLabel}"
    VerticalAlignment="Top" HorizontalAlignment="Right" 
    IsEnabled="{Binding CanLoadProjects}" />

Очевидно, что это не здорово, потому что я больше не могу выполнять команду :), но как только я добавляю команду обратно, она перестает вести себя:

<Button 
    Grid.Column="2" Content="{Binding LoadProjectsLabel}"
    VerticalAlignment="Top" HorizontalAlignment="Right" 
    Command="{Binding LoadProjectsCommand}" />

Оставление IsEnabled привязки не решает проблему, но это похоже на хорошую подсказку.

Код команды модели представления:

public ICommand LoadProjectsCommand
{
    get
    {
        if (_loadProjectsCommand == null)
        {
            _loadProjectsCommand = new RelayCommand(loadProjects, () => CanLoadProjects);
        }
        return _loadProjectsCommand;
    }            
}

Обходной путь

ПодключитеClick событие и избегать Command.Было бы неплохо решить это с точки зрения модели, но это работает:

<Button 
    Grid.Column="2" Content="{Binding LoadProjectsLabel}"
    VerticalAlignment="Top" HorizontalAlignment="Right" 
    IsEnabled="{Binding CanLoadProjects}" 
    Click="loadProjects_Click"/>

Код позади:

void loadProjects_Click(object sender, RoutedEventArgs e)
{
    SettingsViewModel vm = (SettingsViewModel)DataContext;
    vm.LoadProjectsCommand.Execute(null);
}

Ответы [ 2 ]

4 голосов
/ 17 мая 2011

Ответ от другого Тема :

Когда ваш BackgroundWorker завершит работу, вызовите CommandManager.InvalidateRequerySuggested ();

По умолчанию команды запрашиваются WPF только изредка. В противном случае, при каждом вызове «CanExecute» в каждой реализации ICommand было бы много лишних затрат. Вызов вышеупомянутого метода заставляет CommandManager обновляться немедленно.

Это заставит Команды соответствующим образом повторно включить / отключить.

EDIT:

Я использую более простой, но не очень красивый обходной путь. я просто вызываю OnPropertyChanged («MyICommand») для моих команд в моем завершенном событии BackgroundWorker.

EDIT:

здесь - еще одно хорошее решение.

0 голосов
/ 17 мая 2011

Вы должны связать свойство параметра команды с любым обновляемым свойством в viewmodel, и для его выполнения необходимо использовать этот параметр команды для включения кнопки.Если цель параметра команды обновлена, привязка будет включена / отключена в зависимости от возвращаемого значения can excute.

...