1
votes

I am currently implementing a search (more properly "filter") form for my View that uses ApplicationBarIconButtons to drive user interactions with the form: a search button to transition to the VisualState with the form displayed, and one to clear the current filter string value. The textbox that accepts the filter is bound to a property on the ViewModel:

XAML

<toolkit:PhoneTextBox x:Name="txtSearch" Text="{Binding VisitsFilter, Mode=OneWay}" />

ViewModel

private string _visitsFilter;
public string VisitsFilter
{
    get
    {
        return _visitsFilter;
    }
    set
    {
        _visitsFilter = value;
        RaisePropertyChanged("VisitsFilter");
        RebuildVisits();
    }
}

The problem is that ApplicationBarIconButtons don't really have any ability to bind to points on my ViewModel with Commands or similar, so I handle their interactions with it in a code behind handler for its Click event. Doesn't seem like it should be that big a deal... Get the ViewModel from the page's data context and set the value of the bound property:

Code Behind

private VisitsViewModel ViewModel
{
    get
    {
        return this.DataContext as VisitsViewModel;
    }
}

private void abbClear_Click(object sender, EventArgs e)
{
    this.Focus();
    ViewModel.VisitsFilter = string.Empty;
}

If you follow the code above through the setter, you'll see that I set the value of the private string member, then raise the event that the property has changed. I actually have a code behind subscription to this event in my View that's performing other logic about making the "Clear" button visible or not, but the point is it is listening successfully on that event. However, the OneWay binding in the markup above doesn't update the value of the Text property on my PhoneTextBox.

Where's the disconnect here?

1
Can you share a small repro sample? OneWay binding is the default and if the DataContext and your notification function (in your case RaisePropertyChanged) work then it should be fine. - Oren
Ironically my attempts to repro a small example are failing as abysmally as the original code. I'll go comment out bits and pieces and see what's going sideways when I have access to it again and get back to you. - lsuarez

1 Answers

1
votes
  1. It is possible that the method in your setter is taking too long, or doing something that might be messing with the UI thread. Meaning by the time it is released to respond to your PropertyChanged, it missed the opportunity to update...

Try removing RebuildVisits(); from the setter. If that works, and this assumption is correct, then execute RebuildVisits on a different thread.

public string VisitsFilter
{
  get { return _visitsFilter; }
  set { 
         _visitsFilter = value;
         RaisePropertyChanged("VisitsFilter");

         Tasks.StartNew (() => { RebuildVisits();});
       }
    ....

}

2.If it's really a one-way binding that's messing with your updates. Why not make set the TextBox

IsReadOnly = "True" and set the binding to TwoWay