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 Indicator もあります

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

(私はこのプロジェクトで SimpleMVVM ツールキットを使用しています)

ビュー モデル内で、IsBusyIndi​​cator などのプロパティだけでなく、メソッドも宣言しています。

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 セレクター クラスが適用されたリストボックス コントロールを介して結果を読み込みます。

私が見ている問題は、この呼び出しが 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 に答える