0

在视图中,我有一个按钮,可以调用视图模型中的方法

搜索.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 工具包)

在视图模型中,我声明了我的方法以及 IsBusyIndi​​cator 等的属性。

搜索视图模型.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 选择器类的列表框控件加载结果。

我看到的问题是因为这个调用是从 UI 调用的,所以 UI 线程被锁定,直到为集合选择数据模板并返回结果。至此,IsBusy 指标甚至没有触发。

我的问题是有人能指出我应该如何进行这些调用以使 UI 线程不被锁定吗?我是否应该寻找某种后台线程等来进行调用,以便 UI 线程可以调用 IsBusy 指示器等。

如果您需要更多详细信息或其他样品,请告诉我。

提前致谢

4

1 回答 1

0

这里的问题是您锁定了 UI 线程,虽然从表面上看,考虑到事物的结构,一切似乎都应该正常工作,但没有模型中 SearchResult 中的代码,我不能确定您的问题可能在哪里。

此外,您在 *sc_QueryCompleted* 中有一个 null 引用问题,您检查 SearchResults 是否不等于 null,但在您的 else 条件下,您尝试向刚刚验证的对象添加一个值将为 null。修正后的版本如下:

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);
}
于 2011-07-30T01:02:36.127 回答