I've got a TextBox
and a search Button
which has to be enabled only if the TextBox
is not empty.
Since I'm using MVVM Light
, I've bound the button to a RelayCommand
which has a CanExecute
function which just returns a boolean value.
Here's the Button
's code:
<Button Grid.Row="0" Grid.Column="1" HorizontalAlignment="Center" Margin="10" VerticalAlignment="Center" BorderThickness="1" Style="{StaticResource ButtonNoPadding}" Command="{Binding SearchCommand}">
<Rectangle Fill="{StaticResource PhoneForegroundBrush}" Width="40" Height="40" >
<Rectangle.OpacityMask>
<ImageBrush ImageSource="../Assets/AppBar/feature.search.png" />
</Rectangle.OpacityMask>
</Rectangle>
</Button>
and here's the Command
and the property returned by the CanExecute
function:
/// <summary>
/// Boolean that enables/disables the search button
/// </summary>
public bool CanSearch
{
get
{
return !string.IsNullOrEmpty(SearchQuery) && NetworkUtils.IsNetworkAvailable;
}
}
/// <summary>
/// Command used to search for data
/// </summary>
private RelayCommand _searchCommand;
public RelayCommand SearchCommand
{
get
{
return _searchCommand ?? new RelayCommand(ExecuteSearch, () => CanSearch);
}
}
Now, as you may have noticed, the CanSearch
property depends on the lenght of the SearchQuery
string.
The problem here is that this string is always null until I go back and load the page again. This means that my text, and my property, is updated only if I reload the page.
I've followed this answer to fix this problem and having my SearchQuery
update everytime that the text changes (and not only when it loses focus!) but it still won't work.
Here's my TextBox
code:
<TextBox Grid.Row="0" Grid.Column="0" Text="{Binding SearchQuery, Mode=TwoWay}" VerticalAlignment="Center">
<i:Interaction.Behaviors>
<utils:UpdateSourceOnTextChangedBehavior/>
</i:Interaction.Behaviors>
</TextBox>
and here's the attached behavior:
public class UpdateSourceOnTextChangedBehavior : Behavior<TextBox>
{
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.TextChanged += OnTextChanged;
}
protected override void OnDetaching()
{
base.OnDetaching();
AssociatedObject.TextChanged -= OnTextChanged;
}
private void OnTextChanged(object sender, RoutedEventArgs e)
{
AssociatedObject.GetBindingExpression(TextBox.TextProperty).UpdateSource();
}
}
The funny thing is that it actually does what it has to do, because the AssociatedObject.GetBindingExpression(TextBox.TextProperty).UpdateSource();
gets called everytime I change a character in my TextBox
.
Of course the SearchQuery
property raises all the needed events:
/// <summary>
/// Query used to search in the API
/// </summary>
private string _searchQuery;
public string SearchQuery
{
get
{
return _searchQuery;
}
set
{
if (_searchQuery == value) return;
_searchQuery = value;
RaisePropertyChanged(() => SearchQuery);
RaisePropertyChanged(() => CanSearch);
SearchCommand.RaiseCanExecuteChanged();
}
}
Any idea?
The line
return _searchCommand ?? new RelayCommand(ExecuteSearch, () => CanSearch);
doesn't set the _searchCommand field. Perhaps making a new RelayCommand is messing something up?
Try this instead:
return (_searchCommand != null) ? _searchCommand : _searchCommand = new RelayCommand(ExecuteSearch, () => CanSearch);
This lazily creates and sets _searchCommand correctly.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.