In LINQ to SQL, il metodo Strings.Contains è il modo in cui si esprime l'operatore LIKE. Quello che segue è un esempio di come è possibile creare un filter template attorno all'operatore LIKE. Per questo esempio, daremo al nostro modello di filtro personalizzato il nome "Testo".
Il primo passo è aggiornare lo Dynamic Data metadata. Annotare tutte le colonne che si desidera essere in grado di cercare con l'FilterUIHintAttribute in questo modo:
[FilterUIHint("Text")]
Ora abbiamo bisogno di creare il modello di filtro "Testo". Creare il Text.ascx di controllo utente nella cartella modelli di filtro (tipicamente "~/DynamicData/Filtri"):
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="Text.ascx.cs" Inherits="Text" %>
<asp:TextBox runat="server" ID="TextBox1" autocomplete="off" OnTextChanged="TextBox1_Changed" />
Avanti creare il codice dietro, Text.ascx.cs:
public partial class Text : QueryableFilterUserControl {
public override Control FilterControl {
get { return TextBox1; }
}
protected void TextBox1_Changed(object sender, EventArgs e) {
OnFilterChanged();
}
public override IQueryable GetQueryable(IQueryable source) {
var value = TextBox1.Text;
if (String.IsNullOrWhiteSpace(value)) return source;
if (DefaultValues != null) {
DefaultValues[Column.Name] = value;
}
var parameter = Expression.Parameter(source.ElementType);
var columnProperty = Expression.PropertyOrField(parameter, Column.Name);
var likeValue = Expression.Constant(value, typeof (string));
var condition = Expression.Call(
columnProperty,
typeof (string).GetMethod("Contains"),
likeValue);
var where = Expression.Call(
typeof (Queryable),
"Where",
new[] { source.ElementType },
source.Expression,
Expression.Lambda(condition, parameter));
return source.Provider.CreateQuery(where);
}
}
Si noti che non abbiamo fornito alcun modo per l'utente di postback della pagina (e quindi, aggiornare i risultati) dopo aver aggiornato il filtro di testo. Come questione di stile, trovo che i controlli TextBox che il postback automatico siano confusi e trovo ridondante avere un pulsante separato per postback di ogni singolo filtro. Invece, mi piace aggiungere un singolo pulsante al modello di pagina (ad esempio, "~/DynamicData/PageTemplates/List.aspx") che consente all'utente di postback della pagina e aggiornare i risultati. Ecco l'estratto pertinente:
<asp:Panel runat="server" DefaultButton="UpdateFilter">
<asp:QueryableFilterRepeater runat="server" ID="FilterRepeater">
<ItemTemplate>
<asp:Label runat="server" Text='<%# Eval("DisplayName") %>' OnPreRender="Label_PreRender" />
<asp:DynamicFilter runat="server" ID="DynamicFilter" OnFilterChanged="DynamicFilter_FilterChanged" /><br />
</ItemTemplate>
</asp:QueryableFilterRepeater>
<asp:Button runat="server" ID="UpdateFilter" Text="Search" />
</asp:Panel>
Questo è tutto quello che c'è da fare. Gli utenti dovrebbero ora essere in grado di cercare i record che contengono frammenti di testo nelle colonne specificate.
Cosa fa il pulsante UpdateFilter per aggiornare i filtri? Quando implemento questo pulsante non fa nulla quando clicco su di esso. – jpierson
@jpierson Tutto il pulsante è causa di un postback della pagina. Durante il ciclo di vita della pagina del postback, 'TextBox1_Changed' dovrebbe sparare, che è ciò che effettivamente attiva un aggiornamento dei filtri. Se stai riscontrando problemi, dovresti verificare che "TextBox1_Changed" sia effettivamente chiamato. –