Coproject – demo RIA aplikace krok za krokem, díl 7.
V tomto díle přidáme k seznamu z minulého dílu filtrování.
Extension methods
Aby se nám lépe pracovalo, vytvoříme si nejprve několik extension funkcí. V kořeni klientského projektu vytvořte novou třídu jménem Extensions a přidejte do ní tyto funkce:
public static bool IsNullOrWhiteSpace(this string value) { return string.IsNullOrWhiteSpace(value); } public static string FormatWith(this string formatString, params object[] args) { return string.Format(formatString, args); } public static IResult ToSequential(this IEnumerable<IResult> results) { return new SequentialResult(results.GetEnumerator()); }
Za zmínku stojí snad jen ta poslední funkce. Ta zabalí kolekci IResult objektů (jistě si vzpomenete na coroutines z minulého dílu) do jednoho objektu IResult, který při svém spuštění vyvolá postupně (sekvenčně) všechny prvky kolekce. To se hodí hlavně tehdy, když chceme v jedné funkci typu IEnumerable<IResult> vykonat jinou takovou funkci – stačí pak přes yield return vrátit tento sekvenční result.
Filtrování
Abychom mohli filtrovat, musíme umožnit uživateli někam zadat filtrovací kritéria. Proto v ToDoListView nahraďte tlačítko LoadData následujícím kódem:
<Border Style="{StaticResource FilterPanelStyle}"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> <ColumnDefinition Width="auto" /> </Grid.ColumnDefinitions> <TextBox x:Name="Filter" Style="{StaticResource FilterTextBoxStyle}" /> <Button x:Name="LoadData" Grid.Column="1" Content="Search" /> </Grid> </Border>
Kromě toho šumu okolo, kterým jsme zajistili, aby výsledek vypadal trochu k světu, jsme vlastně přidali pouze textbox jménem Filter. Teď už stačí jen upravit funkci LoadData v ToDoListsViewModel podle následujícího kódu:
public IEnumerable<IResult> LoadData(string filter) { CoprojectContext context = new CoprojectContext(); EntityQuery<ToDoList> query = context.GetToDoListsWithItemsQuery().OrderByDescending(l => l.CreatedDate); if (!filter.IsNullOrWhiteSpace()) { query = query.Where(x => x.Name.Contains(filter)); } var result = new LoadDataResult<ToDoList>(context, query); yield return result; Lists = result.Result.Entities; NotifyOfPropertyChange(() => Lists); }
Jak vidíte, pouze jsme přidali parametr a pak podle něj filtrujeme data načítaná ze serveru. Když aplikaci spustíte, zjistíte, že se do parametru dostávají správné hodnoty ze stejnojmenného textboxu – za to může opět Caliburn.Micro. Za zmínku jistě stojí, že tento filtr je přes RIA Services a Entity Framework přenesen až na SQL server, kde je vykonán (v tomto případě se zavolá něco jako …WHERE Name LIKE ‘%něco%’). Tímto způsobem můžete snadno kombinovat různé filtry a postupně proměnnou query filtrovat podle dalších kritérií.
Podle nastavení databáze může být porovnávání řetězců v databází závislé na velikosti písmen. Pokud byste chtěli nebrat při porovnávání v úvahu velikost písmen a databáze vám v tom nepomůže, můžete upravit filtrační kritéria následovně:
query = query.Where(x => x.Name.ToLower().Contains(filter.ToLower()));
To je vše – vzhledem k tomu, jak jsme aplikaci navrhli, nebylo potřeba výraznějších úprav k tomu, abychom přidali filtrování načítaných dat.
Ahoj, chcel by som len upozorniť na little preklep v kóde...má tam byť
if (!Extensions.IsNullOrWhiteSpace(filter))
však?
Ináč super články...robím zaradom :)
Ahoj,
to není překlep, ale extension funkce. Podívej se do definice té funkce a všimni si slova "this" u definice prvního parametru. Výsledkem je, že se tahle statická funkce zdá, že je to funkce na instanci stringu.
Bližší info třeba zde: msdn.microsoft.com/.../bb383977.aspx