0

我有一个TextBox和一个搜索Button,只有当TextBox它不为空时才需要启用它。

由于我使用的是MVVM Light,因此我已将按钮绑定到RelayCommand具有CanExecute仅返回布尔值的函数的 a 。

这是Button's 的代码:

<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>

这是函数Command返回的 and 属性CanExecute

/// <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);
    }
}

现在,您可能已经注意到,该CanSearch属性取决于SearchQuery字符串的长度。

这里的问题是,在我返回并再次加载页面之前,该字符串始终为空。这意味着我的文本和我的属性只有在我重新加载页面时才会更新。

我已经按照这个答案解决了这个问题,并在SearchQuery每次文本更改时进行更新(不仅是当它失去焦点时!)但它仍然无法正常工作。

这是我的TextBox代码:

<TextBox Grid.Row="0" Grid.Column="0" Text="{Binding SearchQuery, Mode=TwoWay}" VerticalAlignment="Center">
    <i:Interaction.Behaviors>
        <utils:UpdateSourceOnTextChangedBehavior/>
    </i:Interaction.Behaviors>
</TextBox>

这是附加的行为:

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();
    }
}

有趣的是它实际上做了它必须做的事情,因为AssociatedObject.GetBindingExpression(TextBox.TextProperty).UpdateSource();每次我在我的TextBox.

当然,该SearchQuery属性会引发所有需要的事件:

/// <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();
    }
}

任何的想法?

4

1 回答 1

0

线

return _searchCommand ?? new RelayCommand(ExecuteSearch, () => CanSearch);

不设置 _searchCommand 字段。也许制作一个新的 RelayCommand 会搞砸一些事情?

试试这个:

 return (_searchCommand != null) ? _searchCommand : _searchCommand = new RelayCommand(ExecuteSearch, () => CanSearch);

这会懒惰地正确创建和设置 _searchCommand。

于 2013-09-30T18:23:39.413 回答