绑定到TextBox的字符串未更新

时间:2013-09-30 18:16:34

标签: c# xaml windows-phone-8 mvvm-light

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

由于我使用MVVM Light,我将按钮绑定到RelayCommand,其CanExecute函数只返回一个布尔值。

以下是Button的代码:

<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以及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字符串的长度。

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

我已经按照this answer解决了这个问题,并且每次文本更改时都会更新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();
    }
}

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

该行

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

未设置_searchCommand字段。也许制作一个新的RelayCommand会弄乱一些东西?

请改为尝试:

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

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