2015-06-17 1 views
1

Я разрабатываю приложение WPF с MVVM. В коде XAML у меня есть Grid с его DataContext, указывающим на ViewModel, и мне нужно знать, можно ли изменить DataContext во время выполнения, чтобы получить доступ к событию по его коду.WPF. Измените DataContext на привязку события для доступа к коду в проекте MVVM

Code-за для зрения:

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     this.DataContext = new MainViewModel(); 
     InitializeComponent(); 
    } 

    private void ValidationEvent(object sender, ValidationErrorEventArgs e) 
    { 
     //Something useful 
    } 
} 

Вот код, который я попробовал в XAML:

<Grid Validation.Error={Binding Path=ValidationEvent RelativeSource={RelativeSource Self}}/> 

код XAML сгенерирует XamlParseException говорить, что это невозможно сделать Связывание с «AddErrorHandler», что это возможно только для DependencyProperty для объекта DependencyObject.

Я не хочу менять DataContext Grid, потому что внутри него есть элементы, которые получают доступ к свойствам MainViewModel, поэтому я просто хочу изменить DataContext для привязки события Validation.Error ... Если это возможно ...

Спасибо.

+0

Что вы хотите сделать внутри этого обработчика событий и почему его нельзя обрабатывать в модели представления? –

+0

Простое тестирование (поэтому событие пуст). Да, это можно обработать в ViewModel, но поскольку это событие, я не могу связать его напрямую с ICommand, мне пришлось использовать что-то вроде «EventToCommand» MVVM Light, и я хочу знать, если это абсолютно необходимо. – MorgoZ

+0

Связывание используется, чтобы сообщить WPF, куда идти, чтобы получить значение. Вы можете изменить источник привязки, чтобы сказать, что он должен идти куда-то, кроме текущего DataContext, для получения значения, как в вашем коде, используя «RelativeSource Self», чтобы изменить источник для этой привязки к самому объекту Grid. Вместо этого вы можете изменить его как объект MainWindow (я бы рекомендовал либо использовать «ElementName», либо «RelativeSource» в «x: Type Window»), однако это не изменит здесь две основные проблемы: «События не знать, как читать привязку, а ValidationEvent - это метод, а не свойство. – Rachel

ответ

2

Validation.Error - событие, а не собственность. Вы не можете устанавливать Bindings для событий.

Вы можете использовать такие вещи, как MVVM Light EventToCommand, или собственную интерактивность Microsoft EventTrigger для связывания команд с событиями.

Но нет ничего плохого в том, что просто добавьте регулярный обработчик событий в код-код и вызовите какой-то код модели просмотра ... Вопреки тому, что многие люди думают, MVVM не запрещает использование код и то, что вы делаете, не сильно отличается от того, что EventToCommand или EventTrigger делают под капотом.

Прежде всего, просто установите имя обработчика события для события Validation.Error.

<Grid Validation.Error="ValidationEvent" /> 

А затем в вашем коде, сделайте все, что захотите.

private void ValidationEvent(object sender, ValidationErrorEventArgs e) 
{ 
    // Something useful 

    // Some call to VM code 
    (this.DataContext as MainViewModel).SomeMethod(); 
} 

Это работает независимо от вашей DataContext (до тех пор, как вы бросили this.DataContext правильный тип, конечно).

Обработчики событий не зависят от вашего DataContext, только с привязками.

+0

Не могли бы вы объяснить это дальше? Вы имеете в виду не привязывать DataContext View к ViewModel и вызывать ViewModel из кода? – MorgoZ

+0

Я думаю, что мы смешиваем вещи здесь. Обработка событий и DataBinding - это две совершенно разные вещи. Вам не нужно менять свой DataContext для обработки событий в коде, события всегда обрабатываются в коде, независимо от того, что ваш DataContext. – almulo

+0

Я обновляю свой ответ с помощью моего предложения кода. – almulo

Смежные вопросы