2013-09-10 3 views
1

Я рабочая реализацией ReactiveUI асинхронного поиском рутины внутри приложения WPF MVVM основана от следующего (унаследованного), например:Несколько привязок из поиска ReactiveUI с использованием ObservableAsPropertyHelper <>

http://blog.paulbetts.org/index.php/2010/07/05/reactivexaml-series-implementing-search-with-observableaspropertyhelper/

public class TheViewModel : ReactiveObject 
{ 
    private string query; 

    private readonly ObservableAsPropertyHelper<List<string>> matches; 

    public TheViewModel() 
    { 
     var searchEngine = this.ObservableForProperty(input => input.Query) 
       .Value() 
       .DistinctUntilChanged() 
       .Throttle(TimeSpan.FromMilliseconds(800)) 
       .Where(query => !string.IsNullOrWhiteSpace(query) && query.Length > 1); 

     var search = searchEngine.SelectMany(TheSearchService.DoSearchAsync); 

     var latestResults = 
      searchEngine.CombineLatest(search, (latestQuery, latestSearch) => latestSearch.Query != latestQuery ? null : latestSearch.Matches) 
       .Where(result => result != null); 

     matches = latestResults.ToProperty(this, result => result.Matches); 
    } 

    public string Query 
    { 
     get 
     { 
      return query; 
     } 
     set 
     { 
      this.RaiseAndSetIfChanged(ref query, value); 
     } 
    } 

    public List<string> Matches 
    { 
     get 
     { 
      return matches.Value; 
     } 
    } 
} 

ReactiveXAML работает, как ожидалось, и я могу легко привязать к свойству Спички, как так

<ListBox Grid.Row="1" Margin="6" ItemsSource="{Binding Matches}" /> 

Однако я бы Li ке реорганизовать TheSearchService.DoSearchAsync() возвращать более сложный результат структуры вроде этого:

public class SearchResult 
{ 
    public string Query { get; set; } 
    public List<string> Matches { get; set; } 
    public int MatchCount { get; set; } 
    public double SearchTime { get; set; } 
} 

Матчи будут по-прежнему быть представлена ​​в виде List<string>, который будет связан с тем же ListBox, но я хотел бы также хотите привязать к свойству метаданных строки на каждом запросе, который возвращает количество матчей и время поиска в каком-то формате, такие как:

string.Format("Found {0} matches in {1}s", x.MatchCount, x.SearchTime) 

Как я могу изменить реализацию ViewModel, чтобы позволить несколько привязок для каждого поиска?

Работа реализация на основе принятого ответа

public class TheViewModel : ReactiveObject 
{ 
    ... 

    private readonly ObservableAsPropertyHelper<SearchResult> results; 

    public TheViewModel() 
    { 
     ... 

     var latestResults = searchEngine.CombineLatest(search, (latestQuery, latestSearch) => latestSearch.Query != latestQuery ? null : latestSearch) 
       .Where(result => result != null); 

     results = latestResults.ToProperty(this, result => result.Result); 
    } 

    ... 

    public SearchResult Result 
    { 
     get 
     { 
      return results.Value; 
     } 
    } 
} 

Вот вид

<StackPanel> 
    <TextBox Text="{Binding Query, UpdateSourceTrigger=PropertyChanged}" 
      Margin="6" 
      FontSize="26" /> 
    <TextBlock> 
     <TextBlock.Text> 
      <MultiBinding StringFormat="Found {0} matches in {1}s"> 
       <Binding Path="Result.MatchCount" /> 
       <Binding Path="Result.SearchTime" /> 
      </MultiBinding> 
     </TextBlock.Text> 
    </TextBlock> 
</StackPanel> 
<ListBox Grid.Row="1" 
    Margin="6" 
    ItemsSource="{Binding Result.Matches}" /> 

ответ

1

В вашем ViewModel, вместо того, чтобы экземпляр спичек создать свойство типа SearchResult говорят MySearchResult. Также реализуйте INotifyPropertyChanged на SearchResult. Обновление SEARCHRESULT после каждой операции поиска

Теперь ваши ListBox привязок будет как <ListBox Grid.Row="1" Margin="6" ItemsSource="{Binding MySearchResult.Matches}" />

Для просмотра результата поиска вы можете иметь TextBlock, как показано ниже:

<TextBlock> 
    <TextBlock.Text> 
     <MultiBinding StringFormat="Found {0} matches in {1}s"> 
      <Binding Path="MySearchResult.MatchCount"/> 
      <Binding Path="MySearchResult.SearchTime"/> 
     </MultiBinding> 
    </TextBlock.Text> 
</TextBlock> 
+1

Спасибо! В соответствии с ароматом ReactiveUI я использовал ObservableAsPropertyHelper . Мое редактирование отражает рабочее решение. – syneptody

 Смежные вопросы

  • Нет связанных вопросов^_^