I have the following XAML. I'm using UWP (Universal Windows Platform) but the problem I'd like to describe also applies to other XAML frameworks such as WPF:
<!-- MyVM is a ViewModel -->
<AutoSuggestBox
QueryIcon="Find"
TextChanged="{x:Bind MyVM.FilterTextChanged}"
Text="{x:Bind MyVM.FilterText, Mode=TwoWay}"/>
This is how it works: when the user types text in the AutoSuggestBox
, MyVM
ViewModel is informed about every key stroke and filters data using FilterText
.
This is how MyVM
looks like:
// Uses INotifyPropertyChanged from MVVMLight
private string filterText;
public string FilterText
{
get { return filterText; }
set { Set(ref filterText, value); }
}
public async void FilterTextChanged()
{
await LoadData(); // uses FilterText to filter data
}
The problem arises when I need to modify FilterText
value, for example to clear it or to set a pre-defined filter. Thanks to the TwoWay binding, the text in the AutoSuggestBox
is displayed correctly but as a "side-effect" the FilterTextChanged
method is called (because the text has changed). I don't want this "side-effect". It is bad from two reasons:
It makes the ViewModel dependent on XAML in the View. What I mean by that is that although I don't call
FilterTextChanged
, it is called anyway when I set theFilterText
value just because it is TwoWay-bound in XAML.It makes automated unit testing impossible. Without XAML, the ViewModel behaves differently: the
FilterTextChanged
method is not called when I set aFilterText
value.
This is a general problem with XAML, MVVM, and TwoWay binding, not restricted to the specific example with AutoSuggestBox
.
How to solve this problem? The main question for me is how to unit test it?