问题描述
我的帐户 CollectionView 未随搜索栏更新。下面的 Xml。
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:viewmodels="clr-namespace:Pricing051721.viewmodels"
x:Class="Pricing051721.MainPage" Title="KR Pricing"
x:Name="This">
<ContentPage.BindingContext>
<viewmodels:MainPageviewmodel/>
</ContentPage.BindingContext>
<StackLayout>
<Button Text="logout" Command="{Binding logoutCommand}" Margin="0,5,5"/>
<SearchBar x:Name="searchBar"
SearchCommand="{Binding PerformSearch}"
SearchCommandParameter="{Binding Text,Source={x:Reference searchBar}}"/>
<CollectionView ItemsSource="{Binding Accounts}" Margin="5">
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout Margin="5" >
<StackLayout.GestureRecognizers>
<TapGestureRecognizer Command="{Binding BindingContext.AccountSelected,Source={x:Reference This}}" CommandParameter="{Binding .}"/>
</StackLayout.GestureRecognizers>
<StackLayout >
<Label FontSize="Medium" Text="{Binding Name}" ></Label>
<Label Text="{Binding Address}"></Label>
</StackLayout>
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</StackLayout>
</ContentPage>
我正在尝试搜索已在视图模型中查询的帐户,因此我不必再次访问数据库。搜索有效,但帐户未更新。
namespace Pricing051721.viewmodels
{
public class MainPageviewmodel : INotifyPropertyChanged
{
public ObservableCollection<Account> Accounts { get; set; }
public INavigation Navigation { get; set; }
public ICommand logoutCommand { get; set; }
AdAuthenticationService authService;
public ObservableCollection<Account> baseAccountList;
public MainPageviewmodel()
{
Accounts = new ObservableCollection<Account> { new Account { AllowUpdate = true,Address = "Wait",Name = "Loading" } };
authService = new AdAuthenticationService();
Task.Run(async () =>
{
if (!authService.IsAuthenticated)
{
var response = authService.Authenticate();
await Update(response.Accesstoken,"");
}
else await Update(authService.Accesstoken,"");
});
AccountSelected = new Command<Account>(async (a) =>
{
if (!a.AllowUpdate)
return;
await Navigation.PushAsync(new UpdateAccountView(a));
return;
var result = await UserDialogs.Instance.PromptAsync(new PromptConfig
{
InputType = InputType.Name,OkText = "Change",Title = "Enter New Column Break",Text = a.ColumnBreak
});
if (result.Ok && result.Text != null && !result.Text.Trim().Equals(""))
{
a.ColumnBreak = result.Text;
isUpdating = true;
var ok = await crm.Update(a);
var message = ok ? "Account Updated!" : "Unable to update!";
await UserDialogs.Instance.AlertAsync(new AlertConfig
{
Title = "Message",Message = message,OkText = "Ok"
});
isUpdating = false;
}
},_ => !isUpdating);
logoutCommand = new Command(new Action(() => {
authService.logout();
Environment.Exit(Environment.ExitCode);
}));
}
//search
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this,new PropertyChangedEventArgs(propertyName));
}
public ICommand PerformSearch => new Command<string>((string query) =>
{
Accounts = SearchAccounts(query);
});
private bool isUpdating = false;
private Crm crm;
public ObservableCollection<Account> accounts;
public async Task Update(string accesstoken,string query)
{
Crm.Setup(accesstoken);
crm = Crm.AuthenticatedCrmService;
var accounts = await crm.GetAccounts();
Accounts.RemoveAt(0);
accounts.ForEach(a => Accounts.Add(a));
}
public ObservableCollection<Account> SearchAccounts(string query)
{
Task.Run(async () =>
{
if (!authService.IsAuthenticated)
{
var response = authService.Authenticate();
await Update(response.Accesstoken,"");
});
baseAccountList = Accounts;
if (!(query == ""))
{
var normalizedQuery = query?.ToLower() ?? "";
List<Account> accountsList = (List<Account>)Accounts.Where(f => f.Name.ToLowerInvariant().Contains(normalizedQuery)).ToList();
ObservableCollection<Account> accounts = new ObservableCollection<Account>(accountsList);
Accounts.Clear();
return accounts;
}
else
{
accounts = Accounts;
return accounts;
}
}
public ICommand AccountSelected { get; set; }
}
}
我不需要一个简洁的解决方案(你可以从我目前的代码中看出),只需要一些可行的方法,提前致谢!
解决方法
我的帐户 CollectionView 未随搜索栏更新
从你的代码来看,你没有发布一些关于 PerformSearch 命令的代码,我不知道你是如何通过搜索栏搜索数据的。我做了一个关于通过搜索栏搜索一些数据的示例,显示在collectionview中,您可以根据以下代码修改您的代码。
<SearchBar
x:Name="searchBar"
SearchCommand="{Binding PerformSearch}"
SearchCommandParameter="{Binding Text,Source={x:Reference searchBar}}" />
<CollectionView Margin="5" ItemsSource="{Binding Accounts}">
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout Margin="5">
<!--<StackLayout.GestureRecognizers>
<TapGestureRecognizer Command="{Binding BindingContext.AccountSelected,Source={x:Reference This}}" CommandParameter="{Binding .}" />
</StackLayout.GestureRecognizers>-->
<StackLayout>
<Label FontSize="Medium" Text="{Binding Name}" />
<Label Text="{Binding Address}" />
</StackLayout>
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
public partial class Page15 : ContentPage
{
public Page15()
{
InitializeComponent();
this.BindingContext = new AccountViewModel();
}
}
public class AccountViewModel
{
public ObservableCollection<Account> AccountList { get; set; }
public ObservableCollection<Account> Accounts { get; set; }
public ICommand PerformSearch { get; set; }
public AccountViewModel()
{
AccountList = new ObservableCollection<Account>();
Accounts = new ObservableCollection<Account>();
for(int i=0;i<30;i++)
{
Account a = new Account();
a.Name = "account" + i;
a.Address = "address " + i;
AccountList.Add(a);
Accounts.Add(a);
}
PerformSearch = new Command(search => {
if(search!=null)
{
string searchtext = (string)search;
if (!string.IsNullOrEmpty(searchtext))
{
Accounts.Clear();
List<Account> list= AccountList.Where((account) => account.Name.ToLower().Contains(searchtext) || account.Address.ToLower().Contains(searchtext)).ToList();
foreach(Account a in list)
{
Accounts.Add(a);
}
}
Accounts = AccountList;
}
else
{
Accounts = AccountList;
}
});
}
}
public class Account
{
public string Name { get; set; }
public string Address { get; set; }
}