Как предотвратить блокировку резьбы пользовательского интерфейса в Silverlight - PullRequest
0 голосов
/ 29 июля 2011

В представлении у меня есть кнопка, которая вызывает метод в моей модели представления

search.xaml

 <TextBox x:Name="txtSearchField"
             Grid.Column="0"
             Style="{StaticResource SearchTxtBoxStyle}"
             Text="{Binding SearchTerm, Mode=TwoWay}"
             KeyDown="txtSearchField_KeyDown"
             ToolTipService.ToolTip="{StaticResource TTsearchField}">
        <i:Interaction.Triggers>
            <ei:KeyTrigger Key="Enter">
                <ei:CallMethodAction
                    TargetObject="{Binding}"
                    MethodName="GetSearchResult"/>
            </ei:KeyTrigger>
        </i:Interaction.Triggers>
    </TextBox>
    <StackPanel x:Name="searchButtons"
                Grid.Row="0"
                Grid.Column="1"
                Margin="3,2,5,2"
                Orientation="Horizontal">
        <Button x:Name="SearchButton"
                Margin="13,1,9,-1"
                ap:AttachedProperties.TabIndex="2"
                Content="{StaticResource btnSearch}"
                Style="{StaticResource blackButton}"
                ToolTipService.ToolTip="{StaticResource TTSavebtn}" >
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="Click">
                    <ei:CallMethodAction
                    TargetObject="{Binding}"
                    MethodName="GetSearchResult"/>
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </Button>

У меня также есть в представлении индикатор IsBusy

 <Grid>
        <!-- Bind IsBusy to IsBusy -->
        <toolkit:BusyIndicator Name="isBusyIndicator" 
            IsBusy="{Binding IsBusy, Mode=TwoWay}"  />
    </Grid>

(я использую SimpleMVVM toolkit с этим проектом)

В модели представления я объявил мой метод, а также свойства для IsBusyIndicator и т. Д.

searchviewmodel.xaml

 public void GetSearchResult()
    {
        //query

       // IsBusy = true;  //Originally set the IsBusyFlag here to see if it would fire 

            SearchResults = this._DataModel.GetSearchResults(this.SearchTerm);
            this.SearchHistory = this._DataModel.AddSearchHistoryItem(this.SearchTerm);   
    }


private bool _isBusy;
    public bool IsBusy
    {
        get { return _isBusy; }
        set
        {
            _isBusy = value;
            NotifyPropertyChanged(m => m.IsBusy);
        }
    }

Затем в модели у меня есть асинхронный вызов к службе WCF

public ObservableCollection<QueryResponse> GetSearchResults(string searchQuery)
    { 
        SearchClient sc = new SearchClient();
        sc.QueryCompleted +=new EventHandler<QueryCompletedEventArgs>(sc_QueryCompleted);
        sc.QueryAsync(new Query { QueryText = searchQuery });
        return this.SearchResults;      
    }  

    void sc_QueryCompleted(object sender, QueryCompletedEventArgs e)
    {
        try
        {
            if (SearchResults != null)
            {
                this.SearchResults.Clear();
                this.SearchResults.Add(e.Result);

            }
            else
            {
                this.SearchResults.Add(e.Result);

            }
           // IsBusy = false;

        }
        catch(Exception ex)
        {
            ex.StackTrace.ToString();
        }
    }

Элемент управления поиском загружает результаты через элемент управления списком, к которому применен класс селектора dataTempalte.

Проблема, с которой я сталкиваюсь, заключается в том, что этот вызов вызывается из пользовательского интерфейса, когда поток пользовательского интерфейса блокируется до тех пор, пока не будут выбраны шаблоны данных для коллекции и возвращены результаты.На данный момент индикатор IsBusy даже не срабатывает.

Мой вопрос: может ли кто-нибудь указать мне, как следует выполнять эти вызовы, чтобы поток пользовательского интерфейса не был заблокирован?Должен ли я искать какой-либо фоновый поток и т. Д., Чтобы сделать вызов, чтобы поток пользовательского интерфейса мог вызвать индикатор IsBusy и т. Д.

Пожалуйста, дайте мне знать, если вам нужно больше деталей или дополнительных примеров.

заранее спасибо

1 Ответ

0 голосов
/ 30 июля 2011

Проблема здесь в том, что вы блокируете поток пользовательского интерфейса, хотя на первый взгляд кажется, что все должно работать правильно, учитывая то, как все структурировано, без кода, который есть в SearchResult в вашей модели, я не могу точно сказать, где вы выпускаетеможет быть.

Кроме того, у вас есть проблема с нулевой ссылкой в ​​* sc_QueryCompleted *, при проверке, если SearchResults не равен нулю, но в другом условии вы пытаетесь добавить значение в объект, который вы только чтопроверено будет ноль.Исправленная версия ниже:

if (SearchResults != null) {
    this.SearchResults.Clear();
    this.SearchResults.Add(e.Result);
} else {
    //I'm guessing at the type from your code
    this.SearchResults = new List<SearchResult)();
    this.SearchResults.Add(e.Result);
}
...