I’m in the middle of writing a Xamarin Forms app and today I needed to add in a contacts search page, and remembered that James Montemagno had created a plugin that exposes contacts in a platform neutral manner so I downloaded it and used it in my app.
I also wanted to add a search bar, and again there’s a control in XF for that, so I ended up with (somewhat simplified) the following XAML…
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<SearchBar x:Name="search" Placeholder="Search">
</SearchBar>
<ListView Grid.Row="1" ItemsSource="{Binding FilteredContacts}"
IsGroupingEnabled="true" GroupDisplayBinding="{Binding Key}"
GroupShortNameBinding="{Binding Key}">
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding Name}" TextColor="Black"
Detail="{Binding PhoneNumber}" DetailColor="Gray">
</TextCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
I have removed some of the XAML as it’s not that important to this post (it’s available in the download). Now, with that in place (and a load of code in the view model which I’ll get to in a minute) I got a UI as follows…
So far so good. Then I needed to hook up the search box, and as I’m using XAML (and if you’re not, you should give it a try as it’s way easier to create UI’s using it) I needed a way to bind to the search box to that I could respond to the TextChanged event.
Another excellent package that you’ll want to use it the Xamarin.Behaviors package by Corrado – massive thanks to him for putting this together, it’s excellent!
Behaviors to the rescue
By adding a behavior into the XAML, I can handle an event – so in this case I added the following to the SearchBar…
<SearchBar x:Name="search" Placeholder="Search">
<b:Interaction.Behaviors>
<b:BehaviorCollection>
<b:EventToCommand EventName="TextChanged"
Command="{Binding SearchTextChanged}"
CommandParameter="{Binding Text, Source={x:Reference search}}"/>
</b:BehaviorCollection>
</b:Interaction.Behaviors>
</SearchBar>
This hooks the TextChanged event of the search bar, calls the SearchTextChangedCommand on my view model, and passes through the value of the Text property of the search bar. Yay!.
Or not.
The problem I found was that my command was being passed a string, but it was the text before the ne character was entered, so say I pressed ‘X’ in an empty search bar, my code would be called with an empty string. Pressing ‘A’ next, my command would get ‘X’, and pressing ‘M” next, my code would get ‘XA’. I was always getting the data just prior to the new character – so I guess that the TextChanged event should be more clearly termed as the TextChanging event.
Anyway, I needed to fix this – so looked at the actual event and it contains two properties, the current text and the new value. All I needed to do was get the new vale of the event arguments and I’d be away.
To the best of my knowledge there is no way to bind to the event arguments, you need to write some additional code (this was true in WPF and Silverlight, I’ve done exactly the same there too). So, I cranked out a new behavior that attaches to the SearchBar’s TextChanged event, and calls the command with the new value of the text property. My XAML is therefore this…
<SearchBar x:Name="search" Placeholder="Search">
<b:Interaction.Behaviors>
<b:BehaviorCollection>
<bh:SearchBarTextChanged Command="{Binding SearchTextChanged}"/>
</b:BehaviorCollection>
</b:Interaction.Behaviors>
</SearchBar>
Here I'm using my SearchBarTextChanged behavior to hook to the SearchTextChanged command, and sure enough now when I type in the search bar I get the desired effect. Excellent!
Filtering in code
In the view model I use James’ contacts plugin to select all contacts that have a mobile phone, and that have at least a forename or surname (my real code blew up on a colleagues iPhone as he has a contact with just a company name). I tuck this list away as the source, and then create a filtered collection from the source and the filter statement.
CrossContacts.Current.PreferContactAggregation = false;
var hasPermission = CrossContacts.Current.RequestPermission().Result;
if (hasPermission)
{
// First off convert all contacts into ContactViewModels...
var vms = CrossContacts.Current.Contacts.Where(c => Matches(c))
.Select(c => new ContactViewModel(c));
// And then setup the contact list
var grouped = from contact in vms
orderby contact.Surname
group contact by contact.SortByCharacter into contactGroup
select new Grouping(contactGroup.Key, contactGroup);
foreach (var g in grouped)
{
_contacts.Add (g);
_filteredContacts.Add (g);
}
}
The above code uses some Linq to select all contacts and group them by first character of their surname. I created a simple Matches(contact) function that checks that the contact has a mobile phone number and also that they have one of forename or surname.
Then I have the code that is called to filter the collection when you type text into the search bar...
private void FilterContacts(string filter)
{
_filteredContacts.Clear ();
if (string.IsNullOrEmpty(filter))
{
foreach (var g in this.Contacts)
_filteredContacts.Add (g);
}
else
{
// Need to do some filtering
foreach (var g in this.Contacts)
{
var matches = g.Where (vm => vm.Name.Contains (filter));
if (matches.Any())
{
_filteredContacts.Add (new Grouping(g.Key, matches));
}
}
}
}
This is a bit ropey but does the trick. As the collection is an ObservableCollection, any changes are shown in the UI immediately.
Code
I’ve created a simple example project (the one shown above) that you can download. Hopefully this will help someone out. I’ve not tried this on Android or Windows Phone as yet, but as none of the code is in the platform specific library I can’t see any reason for it not to work on those platforms too.
Bye for now!
414 comments:
«Oldest ‹Older 401 – 414 of 414キャッシュフローダッシュボードは、企業の資金の流れをリアルタイムで可視化し、健全な経営判断を支援する重要なツールです。入金・出金、売掛金・買掛金、運転資金の状況を一目で把握できるため、資金繰りの不安を軽減し、安定した事業運営を実現します。
本ダッシュボードでは、日次・月次・年次のキャッシュフローを自動集計し、グラフやチャートで分かりやすく表示。将来の資金推移を予測できるため、投資計画やコスト削減施策を的確に立案できます。経理データを手作業でまとめる必要がなくなり、業務効率の大幅な向上にも貢献します。
また、キャッシュフローダッシュボードは、銀行口座、会計ソフト、販売管理システムなどと連携可能で、データを一元管理できます。最新の数値に基づいた分析により、経営者や財務担当者は迅速で正確な意思決定が可能になります。
小規模ビジネスから中小企業まで幅広く対応し、専門知識がなくても直感的に操作できる設計が特長です。資金不足の兆候を早期に察知し、リスクを未然に防ぐことで、企業の成長と安定を力強く支援します。
資金の流れを「見える化」し、経営を次のステージへ導くなら、キャッシュフローダッシュボードの導入が最適な選択です。
キャッシュフロー ダッシュボード
The real story is how fast online buzz can spread and make a simple login screen feel like a big deal.
Join Reddy Anna, India's most trusted platform for live sports and online gaming. Enjoy secure gameplay, exciting bonuses, instant withdrawals, and endless opportunities to win big. Start earning today!
Reddybook is India’s trusted online betting platform offering sports, cricket, and games. Experience secure gaming, fast withdrawals, and nonstop support with Reddy Book, your reliable betting partner.
This topic doesn’t get enough attention. American IV provides strong medical insights in their article on Can Drinking Too Much Water Cause Diarrhea. Great resource for understanding safe hydration.
Sun Associates is a highly reliable Health Insurance Consultant in Erode, offering clear guidance and personalized support to help individuals and families choose the right medical insurance plans. Their team explains policy benefits, coverage options, and claim procedures in a simple and professional manner. They also provide excellent assistance during claim settlement, ensuring a smooth and stress-free experience. Whether you need individual health insurance, family coverage, or specialized policies like cardiac or cancer insurance, Sun Associates is a trusted choice in Erode for complete health protection.
TripLodge Universe offers travelers a smart and Affordable Hotel Staywithout compromising comfort. Designed for guests who value convenience, cleanliness, and cost-efficiency, TripLodge Universe provides well-appointed rooms, essential amenities, and a welcoming atmosphere at a price that fits every budget.
Thanks for sharing this wonderful information, and I totally agree with you. Meanwhile, you can check our blog on Dholera Smart City Plot Price: Your Guide to Investing in India’s First Semi-Conductor Hub. The landscape of Indian real estate is shifting, and the spotlight is firmly on Gujarat. As India’s first operational Smart City and a major Special Investment Region (SIR), Dholera is no longer just a blueprint—it is a reality.
Link: https://sohitduagroup.com/dholera-smart-city-plot-price/
Thank you for sharing this thoughtful post. Continuous learning and adapting to change is very important today. Structured classroom training programs like Login360 help learners gain practical, real-world exposure. Learn more about their industry-oriented Data Science program here: Data Science Course.
Finding reliable academic support can make a huge difference when dealing with complex finance topics and tight deadlines. Many students struggle with financial analysis, case studies, and theoretical concepts, which is why professional guidance becomes essential. Getting Finance assignment help from qualified marketing and finance professionals ensures well-researched, structured, and plagiarism-free work that meets UK academic standards. With expert insights, clear explanations, and timely delivery, students can better understand difficult concepts while improving their grades and confidence. It’s a smart way to balance academic pressure while maintaining quality and accuracy in every assignment.
Great website with interesting insights and well-presented content. Really enjoyed exploring the articles and the perspective shared here.
Also sharing helpful resources: UI/UX Course in Kochi by Login360 and Digital Marketing Course by Login360
Interesting blog with thoughtful insights and well-written content. I really enjoyed browsing through the articles and learning from the perspectives shared here.
Also sharing helpful resources: UI/UX Course in Kochi by Login360 and Digital Marketing Course by Login360
Post a Comment